[英]MySQL sometimes not using the INDEX but sometimes it does
有時我的查詢未使用索引,但有時會使用索引。 你們能解釋一下為什么會這樣嗎?
這是表結構。
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 | +------+-------------+----------------+------+---------------+------+---------+------+-------+-------------+
答案在解釋計划的行列中
在第一種情況下,您有352
在第二個15779
這建議查詢優化器兩個查詢之間的不同策略。
也可能是您在不同的服務器中執行兩個查詢,或者在其他不同條件下無法執行explain。
(sqlbot的評論回答了該問題。)
此復合索引可能會提供進一步的優化:
INDEX(actual_sale, startdate)
但是,這可能會很好地工作,只有actual_sale
不是“太頻繁”為NULL
。 否則,全表掃描會更好,但是優化器可能無法解決這一問題。
您看到的許多列過大。 這樣的過度可能導致性能問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.