2017-03-25 6 views
0

가끔 내 쿼리가 인덱스를 사용하지 않지만 시간이 걸립니다. 왜 그런 일이 일어 났는지 설명 할 수 있니?MySQL에서 때때로 INDEX를 사용하지 않지만 때로는 수행합니다.

이것은 테이블 구조입니다. 첫 번째 쿼리가 인덱스를 치는 않지만, 두 번째는하지, 난 그 쿼리를 만든 유일한 변화가 STARTDATE 부분 출력 아래에서 볼 수 있듯이

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

. 내가 뭘 잘못 했니?

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

입니다 쿼리 최적화 프로그램은 두 쿼리 간의 서로 다른 전략을 사용합니다.

그것은 또한 당신에 의해 또한 최적화에게

+0

동일한 서버에서 쿼리를 실행하고 있는데, 유일한 변경 사항은 startdate NOW()를 사용하면 인덱스가 사용됩니다 .. – Salim

+0

제안 된대로 행 번호가 있습니다. 내 대답은 .. 다른 방법으로 작동하도록 쿼리 최적화 프로그램을 이끌어 낸다는 것입니다. 색인의 사용을 강요 할 수 있습니다. 색인이 더 잘 작동한다고 생각한다면 강제로 특정 색인을 사용하십시오. https://dev.mysql.com/doc/ ref3/5.7/ko/index-hints.html – scaisEdge

+3

@Salim * 유일한 변경은 startdate

0

(sqlbot의 의견이 질문에 대한 대답.)

힘을 설명 evaulable하지 다른 서버 또는 다른 여러 가지 상황에서 두 개의 쿼리를 실행하는 것이 될 수 이 복합 색인을 사용할 수 있습니다.

INDEX(actual_sale, startdate) 

그러나이 방법은 단지 actual_saleNULL이 아닙니다. '너무 자주'입니다. 그렇지 않으면 전체 테이블 스캔이 더 좋을 수 있지만 최적화 프로그램이이를 파악하지 못할 수 있습니다.

지나치게 큰 것으로 보이는 컬럼이 많습니다. 이러한 초과는 성능 문제를 일으킬 수 있습니다.