2017-03-25 4 views
0

Manchmal verwendet meine Abfrage nicht den Index, aber einige Zeit es tut. Kannst du mir erklären, warum es passiert?MySQL verwendet manchmal nicht den INDEX, aber manchmal tut es

Dies ist die Tabellenstruktur.

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 |  | 
+------------------------+---------------+------+-----+---------+-------+ 

Wie Sie unten Ausgabe die erste Abfrage den Index nicht schlagen sehen kann, aber die zweite nicht die einzige Änderung, die ich auf dieser Abfrage gemacht ist startdate Teil. Was mache ich falsch?

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

Der Abfrageoptimierer wird tun, was er für die Abfrage am besten findet. Dies kann bedeuten, dass manchmal ein Index nicht verwendet wird, wenn er der Abfrage nicht hilft. –

Antwort

2

Die Antwort ist in den Reihen Spalte des Plans erklären

im ersten Fall haben Sie 352

in den zweiten 15779

Dies legt nahe, zu Abfrageoptimierer verschiedene Strategien zwischen den beiden Abfragen.

Es könnte auch sein, dass Sie die beiden Abfragen in verschiedenen Servern oder mit anderen verschiedenen Bedingungen ausgeführt wird nicht durch

+0

Ich führe die Abfrage auf dem gleichen Server, die einzige Änderung ist startdate NOW() mache es mit index .. – Salim

+0

dann ist die Nummer der Zeile beteiligt .. wie vorgeschlagen in meiner Antwort .., dass der Abfrage-Optimierer auf andere Weise zu arbeiten .. Sie können die Verwendung von Index zwingen erzwingen die Verwendung von bestimmten Index, wenn Sie denken, der Index funktioniert besser https://dev.mysql.com/doc/ refman/5.7/de/index-tucks.html – scaisEdge

+3

@Salim * die einzige Änderung ist Startdatum

0

evaulable erklären (sqlbot Kommentar beantwortet die Frage.)

weitere Optimierung Macht zur Verfügung mit diesem Composite-Index:

INDEX(actual_sale, startdate) 

Aber die wahrscheinlichnur gut funktionieren würde, 10 ist nicht NULL "zu oft". Andernfalls wäre ein vollständiger Tabellenscan zwar besser, aber der Optimizer erkennt das möglicherweise nicht.

Viele Ihrer Spalten sind übermäßig groß. Solche Überschreitungen können zu Leistungsproblemen führen.

Verwandte Themen