使用CDBcriteria在yii中获取非常慢

时间:2016-12-06 17:38:42

标签: yii

我的表中有大约15000行使用cdbcrieria来获取结果,但加载结果需要花费太多时间,有人可以告诉我获取结果的最快方法

我希望所有获取的行和方法的计数获取最快的结果。请帮助!

以下是我目前使用的代码:

        $criteria = new CDbCriteria;
   // $Criteria->$criteria = 50;
    $currentAction = Yii::app()->controller->action->id;
    if ($currentAction == 'currentstock') {
        $storeid = isset(Yii::app()->session['storeId']) ? Yii::app()->session['storeId'] : 0;
        $criteria->condition .= ' storexparts.storeId="' . $storeid . '" AND  ( partAppStatus="1" OR partAppStatus="15" OR partAppStatus="17" OR partAppStatus="22" ) ';
    } else {
        $userId = Yii::app()->user->id;
        $storeid = isset(Yii::app()->session['storeId']) ? trim(Yii::app()->session['storeId']) : (isset($_REQUEST['storeId']) ? Yii::app()->session['storeId'] = trim($_REQUEST['storeId']) : '');
        $criteria->condition = 'storexparts.storeId="' . $storeid . '"';
        $criteria->condition .= ' AND userxfavparts.userId="' . $userId . '"';
        $criteria->condition .= ' AND userxfavparts.storeId="' . $storeid . '"';
        $criteria->condition .= ' AND (t.partAppStatus="1"';
        $criteria->condition .= ' OR t.partAppStatus="15"';
        $criteria->condition .= ' OR t.partAppStatus="17"';
        $criteria->condition .= ' OR t.partAppStatus="22")';
        // $criteria->order = 't.partCreateDate DESC';
    }
    $criteria->with = array('partUnit0', 'partCat0','fleetname', 'partType0', 'partSubCat0', 'storexparts', 'userxfavparts', 'partBrand0', 'partsalias','partPosXstore');
    if (!empty($_GET['filterProperties'])) {
        $string = implode("@", explode("\\", $_GET['filterProperties']));
        $string = implode("@", explode("'", $string));
        $code = stripslashes(trim($string));
        $criteria->addCondition("partNumber LIKE CONCAT('%', :filterProperties , '%') 
                                OR partsalias.aliasNumber LIKE CONCAT('%', :filterProperties , '%') 
                                OR partType0.typeName LIKE CONCAT('%', :filterProperties , '%') 
                                OR partCat0.catName LIKE CONCAT('%', :filterProperties , '%') 
                                OR partSubCat0.subCatName LIKE CONCAT('%', :filterProperties , '%')
                                OR partDesc LIKE CONCAT('%', :filterProperties , '%') 
                                OR storexparts.partQty LIKE CONCAT('%', :filterProperties , '%') 
                                OR partNotes LIKE CONCAT('%', :filterProperties , '%') 
                                OR partBrand0.brandCode LIKE CONCAT('%', :filterProperties , '%') 
                                OR partUnit0.unitShort LIKE CONCAT('%', :filterProperties , '%')
                                OR partPosXstore.partShelf LIKE CONCAT('%', :filterProperties , '%')
                                OR partPosXstore.partBin LIKE CONCAT('%', :filterProperties , '%')  
                                OR fleetname.fleetcode LIKE CONCAT('%', :filterProperties , '%')  
                                OR fleetname.fleetserialno LIKE CONCAT('%', :filterProperties , '%')  
                                OR fleetname.fleetmodel LIKE CONCAT('%', :filterProperties , '%')   
                                OR fleettype0.typename LIKE CONCAT('%', :filterProperties , '%')  
                                OR fleetbrand0.brandname LIKE CONCAT('%', :filterProperties , '%')  
                                OR engine.engineno LIKE CONCAT('%', :filterProperties , '%')  
                                OR partsalias.aliasBarcode LIKE CONCAT('%', :filterProperties , '%') 
                                ");
        $criteria->params = array(':filterProperties' => $code);
    }



    $criteria->together = true;

    if (isset($_REQUEST['Parts']) && !empty($_REQUEST['Parts'])) {
        if (!empty($_REQUEST['Parts']['partAliasNumber'])) {
            $partId = $_REQUEST['Parts']['partAliasNumber'];
            $criteria->addCondition("partNumber LIKE CONCAT('%', :filterProperties , '%') 
                                OR partsalias.aliasNumber LIKE CONCAT('%', :filterProperties , '%')");
            $criteria->params = array(':filterProperties' => $partId);
        }
    }
    $criteria->compare('partType0.typeName', $this->typeName, true, 'AND', 'LIKE');
    $criteria->compare('partCat0.catName', $this->catName, true, 'AND', 'LIKE');
    $criteria->compare('partSubCat0.subCatName', $this->subCatName, true, 'AND', 'LIKE');
    $criteria->compare('partDesc', $this->partDesc, true, 'AND', 'LIKE');
    $criteria->compare('storexparts.partQty', $this->partQty, true, 'AND', 'LIKE');
    $criteria->compare('partNotes', $this->partNotes, true, 'AND', 'LIKE');
    $criteria->compare('partUnit0.unitShort', $this->unitShort, true, 'AND', 'LIKE');
    $criteria->compare('partBrand0.brandCode', $this->partBrand, true, 'AND', 'LIKE');
    $criteria->compare('partPosXstore.partShelf', $this->partShelf, true, 'AND', 'LIKE');
    $criteria->compare('partPosXstore.partBin', $this->partBin, true, 'AND', 'LIKE'); 

1 个答案:

答案 0 :(得分:0)

非常重要:您的选择必须先于其他任何内容进行优化。如果您使用的是MySQL,则可以查看their official documentation to do it

如果您的选择已正确优化,我建议您使用RDMBS创建数据库视图,以避免使用具有大量数据和元数据的胖ActiveRecords重载您的查询。在MySQL中,构建定义的DML看起来像:

CREATE OR REPLACE VIEW 'mydatabaseview' AS
(
   SELECT 
   ..... your select with all joins and minimal 
   ..... WHERE conditions 
)

回到代码,使用此数据库视图创建模型。 You can generate model with gii code generator。在生成的模型中,protected/models/Mydatabaseview.php确保定义方法primaryKey()

class Mydatabaseview extends ActiveRecord
{
    .....

    // Define this method manually, because your database view
    // don't have primary Key

    public function primaryKey()
    {
        return 'field_from_database_view';
    }

....

最后,在protected/models/Mydatabaseview.php的同一模型中,根据需要使用您的条件:

public function search()
{
    $criteria = new CDbCriteria;
    .......... all your conditions
}

如果问题仍然存在,您可能需要使用Yii Query Builder代替ActiveRecord。它意味着重新设计你的原始概念。