2017-03-25 12 views
0

インデックスがインデックスを使用していないことがありますが、しばらく時間がかかります。あなたは私になぜそれが起こっているのか説明することができますか?MySQLはINDEXを使用していないことがありますが、ときどき実行します。

これはテーブル構造です。

MariaDB [crm]> desc vtiger_project; 
+------------------------+---------------+------+-----+---------+-------+ 
| Field     | Type   | Null | Key | Default | Extra | 
+------------------------+---------------+------+-----+---------+-------+ 
| projectid    | int(11)  | NO | PRI | 0  |  | 
| projectname   | varchar(100) | YES |  | NULL |  | 
| projecttype   | varchar(50) | YES |  | NULL |  | 
| siteaddress   | varchar(500) | YES |  | NULL |  | 
| state     | varchar(100) | YES |  | NULL |  | 
| district    | varchar(100) | YES |  | NULL |  | 
| city     | varchar(100) | YES |  | NULL |  | 
| pincode    | varchar(100) | YES |  | NULL |  | 
| phone     | varchar(100) | YES |  | NULL |  | 
| startdate    | date   | YES | MUL | NULL |  | 
| branch     | varchar(100) | YES |  | NULL |  | 
| customer    | int(11)  | YES | MUL | NULL |  | 
| dealer     | int(11)  | YES |  | NULL |  | 
| contractor    | int(11)  | YES | MUL | NULL |  | 
| architect    | int(11)  | YES | MUL | NULL |  | 
| carpenter    | int(11)  | YES | MUL | NULL |  | 
| productcategory  | varchar(100) | YES |  | NULL |  | 
| brand_preferred  | varchar(100) | YES |  | NULL |  | 
| formal_spec_check  | varchar(3) | YES |  | NULL |  | 
| formal_spec_details | varchar(250) | YES |  | NULL |  | 
| projectstatus   | varchar(25) | YES |  | NULL |  | 
| project_reason_loosing | varchar(100) | YES |  | NULL |  | 
| reason_loosing_deatils | varchar(250) | YES |  | NULL |  | 
| reason_winning_deatils | varchar(250) | YES |  | NULL |  | 
| adjustment    | decimal(25,8) | YES |  | NULL |  | 
| exciseduty    | decimal(25,3) | YES |  | NULL |  | 
| total     | decimal(25,8) | YES |  | NULL |  | 
| subtotal    | decimal(25,8) | YES |  | NULL |  | 
| taxtype    | varchar(25) | YES |  | NULL |  | 
| discount_percent  | decimal(25,3) | YES |  | NULL |  | 
| discount_amount  | decimal(25,8) | YES |  | NULL |  | 
| s_h_amount    | decimal(25,8) | YES |  | NULL |  | 
| currency_id   | int(19)  | NO |  | 1  |  | 
| conversion_rate  | decimal(10,3) | NO |  | 1.000 |  | 
| actual_sale   | varchar(255) | YES |  | NULL |  | 
| expected_sale_in_na | varchar(255) | YES |  | NULL |  | 
| primary_decision_maker | varchar(100) | YES |  | NULL |  | 
+------------------------+---------------+------+-----+---------+-------+ 

あなたは出力の下に見ることができるように最初のクエリは、インデックスを打つんが、もう一つは、私はそのクエリに作られた唯一の変化は、STARTDATE一部ではありません。 何が間違っていますか?

MariaDB [crm]> explain SELECT 
 
    ->  COUNT(projectid) 
 
    -> FROM 
 
    ->  vtiger_project 
 
    -> WHERE 
 
    ->  82582 IN (customer , contractor, architect, carpenter) 
 
    ->   AND projectstatus NOT IN ('Supplied' , 'Closed As Complete', 'Closed As Lost') 
 
    ->   AND actual_sale IS NULL 
 
    ->   AND startdate > NOW() 
 
    -> ; 
 
+------+-------------+----------------+-------+---------------+---------------+---------+------+------+------------------------------------+ 
 
| id | select_type | table   | type | possible_keys | key   | key_len | ref | rows | Extra        | 
 
+------+-------------+----------------+-------+---------------+---------------+---------+------+------+------------------------------------+ 
 
| 1 | SIMPLE  | vtiger_project | range | startdate_idx | startdate_idx | 4  | NULL | 352 | Using index condition; Using where | 
 
+------+-------------+----------------+-------+---------------+---------------+---------+------+------+------------------------------------+ 
 
1 row in set (0.00 sec) 
 

 
MariaDB [crm]> explain SELECT 
 
    ->  COUNT(projectid) 
 
    -> FROM 
 
    ->  vtiger_project 
 
    -> WHERE 
 
    ->  82582 IN (customer , contractor, architect, carpenter) 
 
    ->   AND projectstatus NOT IN ('Supplied' , 'Closed As Complete', 'Closed As Lost') 
 
    ->   AND actual_sale IS NULL 
 
    ->   AND startdate < NOW() 
 
    -> ; 
 
+------+-------------+----------------+------+---------------+------+---------+------+-------+-------------+ 
 
| id | select_type | table   | type | possible_keys | key | key_len | ref | rows | Extra  | 
 
+------+-------------+----------------+------+---------------+------+---------+------+-------+-------------+ 
 
| 1 | SIMPLE  | vtiger_project | ALL | startdate_idx | NULL | NULL | NULL | 15779 | Using where | 
 
+------+-------------+----------------+------+---------------+------+---------+------+-------+-------------+

+2

クエリオプティマイザは、クエリに最も適していると思われる処理を行います。これは、クエリがクエリに役立たない場合、インデックスが使用されないことがあることを意味します。 –

答えて

2

答えは、あなたが二15779

352

これはに示唆を持っている最初のケースで実行計画の行の列に

ですクエリオプティマイザは2つのクエリ間で異なる戦略を実行します。

それはまた、あなたがすることによってさらなる最適化に

+0

同じサーバでクエリを実行していますが、唯一の変更はstartdate NOW()のインデックスを使用すると.. – Salim

+0

は、私の答えでは..別の方法で動作するクエリオプティマイザをリードする..インデックスの使用を強制することができますあなたがインデックスがより良く動作すると思う場合は、特定のインデックスの使用を強制的に追加するhttps://dev.mysql.com/doc/ refman/5.7/ja/index-hints.html – scaisEdge

+3

@Salim *唯一の変更はstartdate

0

(sqlbotさんのコメントは、質問に答える。)

かもしれないを説明evaulableない別のサーバーや他の条件の異なる2つのクエリを実行していることが考えられこの複合インデックスで利用できる:

INDEX(actual_sale, startdate) 

しかし、それはたぶんうまく働くでしょうactual_saleNULLではありません。そうしないと、フル・テーブル・スキャンが改善されますが、オプティマイザがそれを認識しない可能性があります。

多くの列が大きすぎると判断されました。このような超過は、パフォーマンスの問題を引き起こす可能性があります。

関連する問題