Mysql

儘管 WHERE 子句和 EXPLAIN 計劃相同,為什麼 SELECT 時間線不同?

  • October 17, 2016

伺服器版本:亞馬遜 AWS:5.6.19-log MySQL Community Server (GPL)

mysql> select VERSION_NO from bb_table where UPDATE_STAMP > '0' and SID='M02147'  limit 1 ;
Empty set (0.01 sec)

mysql> select FILE_DATA from bb_table where UPDATE_STAMP > '0' and SID='M02147'  limit 1 ;
Empty set (8.05 sec)


mysql> EXPLAIN select VERSION_NO from bb_table where UPDATE_STAMP > '0' and SID='M02147'  limit 1 ;
+----+-------------+----------------+------+----------------------+------+---------+------+------+-------------+
| id | select_type | table          | type | possible_keys        | key  | key_len | ref  | rows | Extra       |
+----+-------------+----------------+------+----------------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | bb_version_mas | ALL  | UPDATE_STAMP_SID     | NULL | NULL    | NULL | 2555 | Using where |
+----+-------------+----------------+------+----------------------+------+---------+------+------+-------------+
1 row in set, 2 warnings (0.00 sec)


mysql> EXPLAIN select FILE_DATA from bb_table where UPDATE_STAMP > '0' and SID='M02147'  limit 1 ;
+----+-------------+----------------+------+----------------------+------+---------+------+------+-------------+
| id | select_type | table          | type | possible_keys        | key  | key_len | ref  | rows | Extra       |
+----+-------------+----------------+------+----------------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | bb_version_mas | ALL  | UPDATE_STAMP_SID     | NULL | NULL    | NULL | 2555 | Using where |
+----+-------------+----------------+------+----------------------+------+---------+------+------+-------------+
1 row in set, 2 warnings (0.00 sec)

VERSION_NO     :varchar(50), NO INDEX
FILE_DATA      :longtext, NO INDEX
WHERE CLAUSE   :SAME FOR BOTH 

如果WHERE先處理子句,則這些SELECTs 的時間應該相同,但這裡不是這種情況。為什麼時間線有很大差異?

無論如何都不滿足子句longtext時,選定的列有什麼區別?WHERE

記憶體被禁用。沒有滿足該WHERE子句的行。我想知道為什麼longtext結果集只有 0 行時必須考慮數據?

如果沒有更多資訊,我們只能猜測為什麼這兩個幾乎相同的查詢以如此不同的效率執行(大約 500 倍)。

但我們可以根據事實做出一些猜測:

  • 沒有索引SIDUPDATE_STAMP因此兩個查詢都進行表掃描。
  • 區別必須在於mediumtext類型。
  • 這種速度上的差異表明第一個查詢可以比較快地進行表掃描(表很小),並發現沒有行滿足條件。但是與第一個查詢相比,第二個查詢非常慢。我的猜測是該mediumtext專欄中有一些長文本。由於text和長varchar列值不儲存在表/索引頁面中,而是儲存在不同的位置,這可以解釋差異。在第二個查詢中,引擎在執行全表掃描時也會獲取這些值(必須從磁碟讀取更多頁面),因此性能很慢。

提高效率的建議。首先使用子查詢查找所需行的主鍵,然後獲取整行:

select file_data 
from bb_table 
where pk = ( select pk            -- where pk is the PRIMARY KEY
            from bb_table
            where update_stamp > '0' 
            limit 1
          ) ;

引用自:https://dba.stackexchange.com/questions/151862