2010-08-16 48 views
5

我有以下情況:在MySQL數據庫中,我有2個MyISAM表,其中一個有420萬行,另一個有320萬行。以下是該表的模式:即使EXPLAIN顯示好計劃,MySQL查詢速度緩慢

表1(4.2M行)

F1 INTEGER UNSIGNED NOT NULL PRIMARY KEY 
f2 varchar(40) 
f3 varchar(40) 
f4 varchar(40) 
f5 varchar(40) 
f6 smallint(6) 
f7 smallint(6) 
f8 varchar(40) 
f9 varchar(40) 
f10 smallint(6) 
f11 varchar(10) 
f12 tinyint(4) 
f13 smallint(6) 
f14 text 

表2(320M行)

F1 INTEGER UNSIGNED NOT NULL PRIMARY KEY 
f2 INTEGER UNSIGNED NOT NULL 

表2是在不同的數據庫,但我使用一個存儲查詢這兩個表的過程。兩個表格之間的關係是Table1.F1的關係可能高達約。 Table2.F1(外鍵)中有100行匹配,並且這些匹配鍵將返回Table2.f2的值。 我有一個索引IX1(F2(15),F3(10))上表1和表索引IX2(F1,F2)和IX3(F2)2

我正在運行中的查詢如下:

SELECT g.F1 
FROM DB1.Table1 g 
INNER JOIN DB2.Table2 gp ON g.F1 = gp.F1 
WHERE (gp.f2 = 452677825) AND 
(g.f2 = 'A string value') LIMIT 0,56 

這個查詢有時是非常快的(< 1秒),但改變這種g.F2進行比較,導致其採取甚至超過11,有時甚至30秒的查詢字符串值。我不明白爲什麼這樣。以下是SELECT執行的EXPLAIN的輸出。

1, 'SIMPLE', 'g', 'ref', 'PRIMARY,IX1', 'IX1', '17', 'const', 901, 'Using where' 
1, 'SIMPLE', 'gp', 'ref', 'IX3,IX2', 'IX2', '8', 'DB1.g.F1,const', 1, 'Using index' 

這似乎是一個很好的執行計劃。解釋首行中的行數最多爲2000,但我不明白爲什麼這需要超過幾分之一秒才能返回結果。我還在查詢上運行了分析器,並注意到查詢花費了99.9%的時間在「發送數據」階段。任何人都可以解釋爲什麼這樣,以及可以做什麼來優化查詢?

由於提前, 添

+0

執行較慢的查詢是否也傾向於那些返回更多數據的查詢? – 2010-08-16 22:27:25

+0

你好。謝謝你的評論。查詢將全部返回至多56行,因爲我正在限制該陳述。但是,作爲一般規則,EXPLAIN頂行中的行越多,所用時間越長,但情況並非總是如此。 – Tim 2010-08-16 22:33:59

+0

增加表1中IX1的f2中包含的字符數量的大小是否對性能有任何影響?具體來說,是增加到40個這樣的東西嗎? – 2010-08-16 22:35:22

回答

1

我不是這方面的專家,但這裏有幾個想法:

查詢速度需要更長的時間時g.F2變化是因爲緩存。 MySQL會保存每個查詢的結果(直到緩存已滿),但是新的查詢在空的緩存上運行,所以它們需要更長的時間。您不應該基於此進行優化。 (見How to measure accurately

我無法從你的信息告訴ggp表是否有更好的特異性(好像gp?)的where子句中,但你可能想嘗試一個子查詢來代替。 (見How to force the inner query to execute first

關於分析,有可能你打的一樣超過RAM分配(使用交換來說是災難性的表現),這將不會是明顯的explain,還是explain只是錯在這種情況下,物理閾值。

+0

嗨, 感謝您的評論。正如你所建議的那樣,現在我已經改變了上面的查詢來使用IN而不是join。現在查詢如下: SELECT g.F1 FROM(SELECT g.F1 FROM DB1.Table1 g WHERE(g.f2 ='abc'))AS WHERE A.F1 IN(SELECT gp.F1 FROM DB2。表2 gp WHERE(gp.f2 = 452677825))極限0,56 並且查詢運行速度快很多(〜1s,2s max)。我的任務是儘可能地減少這個問題! – Tim 2010-08-17 19:52:26

0

如果你可以嘗試調整你的my.cnf,你想玩的財產是key_buffer_size。如果您找到這些文件並總計文件大小(例如ls -lh /var/lib/mysql/dbname/*.MYI),則可以粗略估計MyISAM索引存儲在.MYI文件中的關鍵緩衝區需要適合的大小所有的索引都在。MySQL文檔不建議超過系統內存的25%。

0

這兩個表之間的關係是Table1.F1的關係可能高達約。 100行中Table2.F1

爲了澄清,是Table1.F1Table2.F1一個到一,或一對多的關係?對我來說,這個陳述意味着一對多,但是從模式來看,每個字段都是主要的(即唯一的)鍵。

無論如何,我懷疑g.f2(15)的制服是不統一的,並且當統計異常值被擊中時,性能會相應下降。

做的

SELECT f2(15) AS f2_15, COUNT(*) AS cnt 
FROM Table1 
GROUP BY f2(15) 
ORDER BY cnt DESC 

結果顯示一些顯著異常?