2013-03-30 148 views
3

我目前上傳datafeeds到我的數據庫。在我的數據庫被轉儲,因爲超過1crores記錄在那裏。我需要改善或提高我的MYSQL查詢性能在我的網站。這裏我執行查詢下面....如何提高MYSQL查詢的性能?

select SUM(SPRICE) AS Tot, MIN(SMIN) AS Min from 
(SELECT COUNT(LS.SALEPRICE) AS SPRICE, MIN(LS.SALEPRICE) AS SMIN 
FROM `linkshare` LS 
WHERE LS.`PRODUCTNAME` LIKE '%DVS Men\'s Comanche Skate Shoe%' 
UNION 
SELECT COUNT(CJ.PRICE) AS SPRICE, MIN(CJ.PRICE) AS SMIN 
FROM `cjfeeds` CJ 
WHERE CJ.NAME LIKE '%DVS Men\'s Comanche Skate Shoe%') AS xyz 

在這上面的查詢,其在本地數據庫完美的工作和我的數據庫包含較少的5萬多條記錄...如何提高我在直播服務器查詢?請指導我.....

Explain Query

另外我的查詢耗時39.4626秒。我怎樣才能減少這個查詢運行時間?

+0

您需要規範化數據庫。 –

+0

[選擇比費雪價格我的第一個SQL Server](http://grimoire.ca/mysql/choose-something-else)?如果你想要一個嚴肅的評論:你的LIKE與通配符匹配,你的字符串的開始和結束可能對你的查詢造成最大的傷害。 –

+1

請注意,您應該在查詢中使用'UNION ALL'而不是'UNION'(默認爲'UNION DISTINCT')。 –

回答

0

使用EXPLAIN找出什麼是引擎蓋下回事

3

確定,要與你的查詢更具體的編輯我的回答對第一筆交易,早前建議的工作,但你的查詢是相當瘋狂讓我們討論爲什麼。

您需要的一切實際上都是在EXPLAIN輸出中,您的UNION正在導致340萬個元組訪問,並且派生表查詢(連接之後)大約是90萬元。

  • Add an index上PRODUCTNAME兩個表

  • 聯盟?跆拳道?我假設這裏發生了什麼是你有兩個相似/相同的表,你正在做一個這個相當不友好的過濾器查詢的聯盟,以基本上連接到另一個。 這是第一個警告標誌,如果您可以簡化此操作並且使用一個枚舉類型爲enum的表(例如, type(LS | CJ)或外鍵和類型表,具體取決於您的要求。

  • 假設你不想因爲某種原因永久性地完成這個操作(你應該),你可以從這兩個選擇中對這個計算執行create a temporary table。一旦你把所有信息放在一張表中,因爲你正在做一個簡單的選擇你的計數,總和會很快。

MySQL有一個EXPLAIN命令,您可以在任何查詢中加前綴,例如

EXPLAIN select SUM(SPRICE) AS Tot, MIN(SMIN) AS Min from (SELECT COUNT(LS.SALEPRICE) AS SPRICE, MIN(LS.SALEPRICE) AS SMIN FROM `linkshare` LS WHERE LS.`PRODUCTNAME` LIKE '%DVS Men\'s Comanche Skate Shoe%' UNION SELECT COUNT(CJ.PRICE) AS SPRICE, MIN(CJ.PRICE) AS SMIN FROM `cjfeeds` CJ WHERE CJ.NAME LIKE '%DVS Men\'s Comanche Skate Shoe%') AS xyz; 

對於初學者來說,輸出可能有點神祕,請查看tutorial瞭解更多信息。總的來說:

  • 儘可能避免'LIKE%blah%'風格查詢,因爲Mark Ba​​nnister建議這些查詢不會使用您創建的任何索引。
  • 在選擇中使用的任何字段(在具有超過一千行的表格中)創建索引。
  • 保持快速增長的表格儘可能地精益
  • 儘可能使用固定寬度的列, char/varchar而不是TEXT/BLOB
  • 如果您在大型數據集上運行復合緩慢查詢,請考慮緩存它/ mygof表緩存大小/ tuning

    總之,總是嘗試做精確的字符串匹配,因爲它們可以被索引。你的問題源於規範化程度較低的表格結構。規範化只是意味着(以高級別的非技術方式),您已經以減少重複的方式組織數據,因此更加一致。這樣做的好處是它可以更容易地對其進行有效的查詢。 如果您認爲需要通配符查詢,則可能需要將產品分類爲 分成'shoes'這樣的類別,爲此,請添加一個product_categories表,其中包含類似於| category_id,category_name |的模式。然後在你的產品表中(如果一個產品只能在一個類別中)添加一個外鍵,例如category_id,向category_id字段添加索引,然後通過category_id查詢產品

例如, select * FROM products where category_id = 5

如果您認爲您需要對數據進行模糊匹配,那麼確實聽起來好像有點混亂。如果這是不可避免的,那麼看看你的devops人員是否可以設置一個讀取從屬設備,這樣你的緩慢查詢就不會傷害任何重要的系統。

+0

如果你錯誤地組裝它,那麼調整引擎是毫無用處的。 –

+1

請注意,'''blah%'''可能可以使用索引,但'like'%blah%''不太可能使用索引。 –

+0

我在價格字段中創建了索引。但我如何在我的查詢中使用這個索引。 –

-1

您可能會看到在性能小的改進,如果你改變你的查詢是:

select SUM(SPRICE) AS Tot, MIN(SPRICE) AS Min from 
(SELECT SALEPRICE SPRICE 
FROM `linkshare` 
WHERE `PRODUCTNAME` LIKE '%DVS Men\'s Comanche Skate Shoe%' 
UNION ALL 
SELECT PRICE SPRICE 
FROM `cjfeeds` 
WHERE NAME LIKE '%DVS Men\'s Comanche Skate Shoe%') AS xyz 

- 但是,你不可能永遠能夠顯著提高你的表現;您正在執行的唯一選擇是在LIKE '%DVS Men\'s Comanche Skate Shoe%'的字段中,該字段將無法使用索引,因此需要全表掃描這兩個表才能派生結果。

+0

Hi @Mark Ba​​nnister,我的查詢使用少量數據在本地數據庫中工作。但我的實時數據庫表包含超過1000萬條記錄。所以它需要更多的加載... –