duancheng3342 2011-07-03 16:05
浏览 53

我可以使用php函数执行相当于mySQL左连接的操作吗?

The problem I am having is that using the current function below is taking much too long to load. The two tables that are being joined consist of thousands of rows apiece. The specific function that holds the table join is the &getFields() function in the model section below.

I was thinking that I could possibly have a function that initially checked whether the request was to edit or add new and then deal with separating the table join on only edit queries (No clue as to how to accomplish this).


Call From Page Initial Page - using an html form with post method

if(count($this->fields)){
    for($i=0;$ifields);$i++){
        $field =& $this->fields[$i];
        $se = $field->section;
        $ti = $field->title;
        $ft = $field->type;
        $na = $field->name;
        $fva = $field->field_value;
        $nu = $field->unit;
        switch($se){
            case 'header' :
                        echo 'input type="blah...


Controller Directing Traffic To Model

function __construct() {
    parent::__construct();
    $this->registerTask('add','edit');
    JRequest::setVar('view','cpanel');
}

function edit() {
    JRequest::setVar('layout','form');
    parent::display();
}

function save() {
    $model = $this->getModel('cpanel');
    $msg = $model->store();
    $link = ;
    $this->setRedirect($link, $msg);
}


Model That Holds The Actual Functions

function __construct() {
    parent::__construct();
    global $mainframe;

    $array = JRequest::getVar('cid',  0, '', 'array');
    $this->setId((int)$array[0]);
}

function setId($id) {
    // Set id and wipe data
    $this->_id      = $id;
    $this->_data    = null;
}

function &getItem() {
    if(empty($this->_data)) {
        $query = ' SELECT * FROM #__directory_entry WHERE id = '.$this->_id;
        $this->_db->setQuery( $query );
        $this->_data = $this->_db->loadObject();
    }
    if(!$this->_data)   {
        $session =& JFactory::getSession();
        $post = $session->get('post');
        $this->_data->id = 0;
        $this->_data->title = isset($post['title'])?$post['title']:null;
    }
    return $this->_data;
}

function &getFields() {
    $query = 'select f.*, ef.field_value from #__directory_field as f left join
#__directory_enf as ef on (f.id = ef.field_id and ef.entry_id = '.$this->_id.') where
f.published = 1 order by f.ordering asc';
$this->_db->setQuery( $query ); $fields = $this->_db->loadObjectList(); $session =& JFactory::getSession(); if($session->has('post') and !$this->_id) { $post = $session->get('post'); for($i=0;$ifield_value = isset($post['field_'.$fields[$i]->name])?$post['field_'.$fields[$i]->name]:null; } return $fields; } function store() { // Check for request forgeries JRequest::checkToken() or jexit( JText::_('Invalid Token') ); $post = JRequest::get( 'post' ); $session =& JFactory::getSession(); $session->set('post', $post); if($post["title"] == "") return JText::_('Please enter the title'); $query = 'select * from #__directory_field where published = 1'; $this->_db->setQuery( $query ); $fields = $this->_db->loadObjectList(); for($i=0;$irequired and $post['field_'.$fields[$i]->name] == "") return JText::_($fields[$i]->title . ' is required field and can not be left blank.'); } if(!$post["id"]) { $date =& JFactory::getDate(); $post['create_date'] = $date->toMySQL(); $post['ordering'] = 1; $query = 'select ordering from #__directory_entry order by ordering desc limit 1'; $this->_db->setQuery( $query ); $post['ordering'] += $this->_db->loadResult(); $post['published'] = 1; } $me =& JFactory::getUser(); JTable::addIncludePath(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_joomd'.DS.'tables'); $row =& JTable::getInstance('entry', 'Table'); if (!$row->bind( $post )) return JText::_('Sorry some Error Occurred.'); if (!$row->store()) return $this->_db->getErrorMsg(); if(!$post['id']) { $post['id'] = $this->_db->insertid(); JRequest::setVar('id', $post['id']); $msg = JText::_('Entry successfully added!'); $query = 'insert into #__directory_enu (entry_id, user_id) values ('.$post['id'].', '.$me->id.')'; $this->_db->setQuery( $query ); $this->_db->query(); } else $msg = JText::_('Entry successfully Updated!'); $max_size = 10000000; jimport('joomla.filesystem.file'); $time = time(); for($i=0;$itype == "image") $allowed = array('.jpg', '.jpeg', '.gif', '.png'); elseif($field->type == "file") $allowed = array('.doc', '.docx', '.pdf', '.txt', '.exl', '.xls', '.xlsx', '.jpg', '.jpeg', '.gif', '.png', '.zip'); $flag = true; $query = 'select count(*) from #__directory_enf where entry_id = ' . $post["id"] .' and field_id = ' . $field->id; $this->_db->setQuery( $query ); $count = $this->_db->loadResult(); if($field->type == "image" or $field->type == "file") { $image = JRequest::getVar("field_".$field->name, null, 'FILES', 'array'); $image_name = str_replace(' ', '', JFile::makeSafe($image['name'])); $image_tmp = $image["tmp_name"]; if($image_name "") { $ext = strrchr($image_name, '.'); if(!in_array($ext, $allowed)) return sprintf(JText::_('File type for %s is not allowed.'), $field->title); if(filesize($image_tmp) > $max_size) return sprintf(JText::_('File size for %s exceeds the maximum file size.'), $field->title); if(move_uploaded_file($image_tmp, JPATH_SITE.'/files/'.$time.$image_name)) $post["field_".$field->name] = $time.$image_name; else return sprintf(JText::_('Sorry File for %s could not be uploaded.'), $field->title); } else $flag = false; } if($flag) { if($count) { $query = 'select id from #__directory_enf where entry_id = '.$post["id"].' and field_id = ' . $field->id; $this->_db->setQuery( $query ); $field_id = $this->_db->loadResult(); $update = new stdClass(); $update->id = $field_id; $update->field_value = $post["field_".$field->name]; $this->_db->updateObject('#__directory_enf', $update, 'id'); } else { $insert = new stdClass(); $insert->id = null; $insert->field_id = $field->id; $insert->entry_id = $post["id"]; $insert->field_value = $post["field_".$field->name]; $this->_db->insertObject('#__directory_enf', $insert, 'id'); } } } $session->clear('post'); return $msg; }
  • 写回答

1条回答 默认 最新

  • doudu2404 2011-07-03 18:44
    关注

    Left Join is the fastest method, but you have written your query in such a way that it will be very slow.

    SELECT f.*, ef.field_value
       FROM #__directory_field AS f
       LEFT JOIN #__directory_enf AS ef ON (f.id = ef.field_id AND ef.entry_id = $this->_id)
       WHERE f.published = 1
       ORDER BY f.ordering ASC
    

    Your ON clause is the main problem. Written this way you are ant trailing through every record, and not putting good use to indexes. You will want to reverse your table order, and put the id match in the where clause. Something like this.

    SELECT ef.field_value, f.*
       FROM #__directory_enf AS ef
       LEFT JOIN #__directory_field AS f ON f.id = ef.field_id
       WHERE f.published = 1 AND ef.entry_id = $this->_id
       ORDER BY f.ordering ASC
    

    You will then want to make sure your database has indexes on both the f.id and ef.entry_id fields. This should make your query many many times faster.

    评论

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?