簡體   English   中英

MySQL 5.5查詢優化

[英]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的唯一方法是擁有一個覆蓋所有WHEREORDER 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 KEYUNIQUE KEY 將第二列添加到唯一鍵不會使其變得“更獨特”或其他有用的東西。 InnoDB表聚集在PK周圍,因此以PK開頭的另一個索引幾乎總是浪費。 刪除該唯一鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM