[英]Mysql 5.5 Query Optimisation
努力使mysql 5.5查詢能夠有效地與現有索引一起使用,據我所知,這是有限的知識和經驗,足以完成這項工作。 該查詢目前執行得足夠快,但是在擴展之前,我寧願這樣做。
表結構:
CREATE TABLE tasks (
taskid INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
clientid INT(10) UNSIGNED NOT NULL,
taskdata CHAR(40) NOT NULL,
tasktype SMALLINT(5) UNSIGNED NOT NULL,
clientstaskref CHAR(40) NOT NULL,
deadline DATETIME NOT NULL,
canbeongoing BIT(1) NOT NULL,
isunderway BIT(1) NOT NULL,
checkenabled BIT(1) NOT NULL,
lastupdated DATETIME NOT NULL,
PRIMARY KEY (taskid),
UNIQUE KEY clientstaskref (clientstaskref),
UNIQUE KEY checkenabled (checkenabled,clientid,taskid),
KEY deadline (deadline),
KEY lastupdated (lastupdated),
KEY isunderway (isunderway),
KEY taskdata (taskdata),
KEY tasktype (tasktype),
KEY clientid (clientid,tasktype)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE tasktypes (
typeid SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
subtypeid SMALLINT(5) UNSIGNED NOT NULL,
typedesc CHAR(40) NOT NULL,
rectype CHAR(40) NOT NULL,
checkenabled BIT(1) NOT NULL,
firstadded DATETIME NOT NULL,
lastupdated DATETIME NOT NULL,
isaccountable BIT(1) NOT NULL,
PRIMARY KEY (typeid),
UNIQUE KEY checkenabled (checkenabled,subtypeid,typedesc),
UNIQUE KEY typeid (typeid,typedesc),
UNIQUE KEY subtypeid (subtypeid,typedesc),
KEY typedesc (typedesc)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
流氓查詢:
SELECT a.taskid, a.taskdata, b.typedesc, a.deadline, a.checkenabled
FROM tasks AS a, tasktypes AS b
WHERE a.clientid = 220
AND a.tasktype = b.typeid
ORDER BY b.typedesc
解釋輸出:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ref tasktype,clientid clientid 4 const 56 Using temporary; Using filesort
1 SIMPLE b eq_ref PRIMARY,typeid PRIMARY 2 testing.a.tasktype 1
顯然,我想擺脫Using臨時文件; 使用文件排序!
抱歉,如果該問題重復了一個現有的問題,但是卻出現了許多稍微相似的問題,這似乎需要花費數周的時間才能找到可以提供解決方案的問題!
Unpanic
不,您應該擺脫“使用臨時;使用文件排序”這一點並不明顯。 它們是執行查詢的最快方法。
讓我們剖析查詢...
您正在JOINing
兩個表。 但是你過濾在一( a.clientid
)但另一方面(排序b.typedesc
)。 避免tmp + filesort的唯一方法是擁有一個覆蓋所有WHERE
和ORDER BY
子句的索引。 這是不可能的。
因此,相反,優化器決定首先對a.clientid
進行“過濾”,希望將有趣的行數降低到估計值56。然后,它以最佳方式將JOINs
eq_ref..PRIMARY
到另一個表( eq_ref..PRIMARY
)。 最后,它對〜56行進行排序。
別失望 “使用臨時;使用文件排序”是錯誤的估計。 如果一切順利,“ temp”將是RAM中的一個MEMORY
表,“ filesort”將不涉及任何“ file”,而只是對Memory表進行qsort。
其他一些技巧 ...
CHAR(..)
。 VARCHAR(..)
可能更好。 isunderway
),這樣的索引幾乎從未使用過。 JOIN...ON...
語法。 PRIMARY KEY (typeid)
和UNIQUE KEY typeid (typeid,typedesc)
: PRIMARY KEY
是UNIQUE KEY
。 將第二列添加到唯一鍵不會使其變得“更獨特”或其他有用的東西。 InnoDB表聚集在PK周圍,因此以PK開頭的另一個索引幾乎總是浪費。 刪除該唯一鍵。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.