2010-06-23 61 views
2

簡單情況下,兩列表[ID,TEXT]。文本列有1-10個單詞短語。 300,000行。什麼是在表上運行優化,做出如此巨大的差異?

運行查詢:

SELECT * FROM row 
WHERE text LIKE '%word%' 

...把​​0.1秒。好。
因此,我創建一個第二柱,表現在有:[ID,TEXT2,TEXT2] 我製成TEXT2 = TEXT(使用UPDATE table SET TEXT2 = TEXT]

然後我再次運行關於 '%字%' 查詢,並。它需要2.4秒


這讓我非常非常難住了,但之後不少死衚衕,我運行OPTIMIZE在桌子上,和它關係到0.2秒左右

兩個問題:

  1. 有沒有人知道數據結構如何在如此混亂的情況下得到自身的效果,即數據翻倍將該查詢的搜索時間增加了24倍?
  2. 像這樣的未索引搜索的標準是否以基礎表數據結構的速度增加而不是正在搜索的實際列中的數據?

謝謝!

+0

有關數據庫的一些知識是,當查詢命中優化器時,它並不總是選擇與數據相同的路徑。我更熟悉Oracle(在SQL Server上少一點) - 都試圖在查詢必須與文本完全匹配的緩存中查找查詢。如果它匹配,則稱它爲軟解析,因爲解析已經完成。否則,它必須做一個硬解析,然後軟解析... – 2010-06-23 01:23:09

+0

如果你使用通配符啓動查詢鍵,無論如何它都要進行表掃描。 – dkretz 2010-06-23 01:45:14

+0

小馬...這是OPTOMIZE作爲清理數據的mySQL函數 - 我不是在討論如何優化實際查詢。 Dorifer ...是的,我知道它會進行全表掃描。問題依然存在。 – 2010-06-23 11:15:02

回答

0

聽起來像你是查詢緩存的受害者。第二次運行查詢時(在優化之後),它已經有了緩存的答案,因此結果會立即返回。您是否嘗試過搜索不同的搜索字詞?試着用緩存運行查詢關掉像這樣:

SELECT SQL_NO_CACHE * FROM row WHERE text LIKE '%word%' 

要看看這改變的結果,或嘗試搜索不同的單詞,但結果同樣數量,以確保您的服務器不只是返回緩存值。

+0

如果它被緩存了,它不應該像以前那樣以較快的速度返回答案嗎? – 2010-06-23 01:16:44

+0

需要2.4秒的查詢在更新語句後發生,因此無法使用查詢緩存,因爲基礎數據已更改。然而,優化表並不會更改基礎數據,因此結果會很快恢復。我在考慮優化表命令並不重要,而且它實際上運行得更快,因爲結果被緩存了,底層數據沒有改變。 – Kibbee 2010-06-23 01:29:55

+0

但是OP在問爲什麼需要更長的時間... – 2010-06-23 01:31:41

0

它第一次進行表掃描,聽起來正確的時機 - 沒有涉及索引。

然後你添加了索引,mysql優化器沒有注意到你在前面有一個通配符,所以它掃描整個索引以找到記錄,然後需要兩個更多的讀取(一個到PK,然後一個從那裏進入表格)以獲取數據記錄。

OPTIMIZE可能只是更新優化器的統計信息,所以它知道它應該再次掃描表。

+0

任何表格都沒有索引。兩名查詢者都在按照預先掃描的方式進行全表掃描。 – 2010-06-23 11:15:20

+0

你最終的文件大小是否相同? (這是MyISAM表,對吧?)考慮到你使用的是惡性通配符查詢,你到底想要解決什麼問題?我猜測它會把表格從可以加載到內存中的東西和需要交換磁盤的東西轉移過來,但是你可以從數據庫統計中找到它。 – dkretz 2010-06-23 16:50:06

+0

運行optomize從35MB到28MB。但我不認爲這是問題,因爲我也嘗試將VARCHAR列更改爲CHAR(250)列。這使得表格大約有70MB,但與OPTOMIZE相比,它的效果相差20倍。 – 2010-06-23 23:12:51

0

我會認爲這種差異是由於增加的行長度導致表在磁盤上碎片化。優化會排除這個問題,導致搜索時間恢復正常(給予或稍微)。

相關問題