2013-04-04 55 views
2

我有什麼可以描述爲我需要優化的大胖子MySQL查詢。查詢所做的是選擇與反向鏈接處理有關的數據。優化包含子查詢的MySQL查詢

通過反向鏈接處理我的意思是將大約100,000個鏈接添加到數據庫。鏈接被選中並分批捲曲,尋找反向鏈接到我的網站。

我選擇這個查詢中的信息是:

  • complete - 已處理完成的(布爾1或0)
  • current_step - 對我們是什麼步驟總分3(1,2或3)
  • percent - 做了什麼百分比是我與我在(0-100)
  • total_rows步驟 - 所有行的數據庫中的一個完整的計數與 該表密鑰ID(整數)
  • live_rows - 與現場的反向鏈接到我的網頁(整數)
  • dead_rows發現鏈接的數量 - 鏈接發現,沒有一個反向鏈接(整數)

注數:當前步驟通過查看checked列的MAX()值來計算。如果鏈接未找到,我們檢查鏈接兩次。所以當工具第一次開始運行時,所有的值都被設置爲零(因爲處理尚未開始),所以我們希望當前步驟成爲步驟1.然後,我們處理所有行,並且所有checked值都設置爲1並且百分比將返回爲步驟1中的100.00,然後該程序開始對第一次發現死亡的鏈接進行雙重檢查。隨着第二次檢查,一些行被設置爲2,因此MAX(checked)在步驟2中返回2。一旦完成第二步,程序將processing_complete列更改爲1,我們返回3作爲完成的當前步驟。我們返回3是因爲它導致UI更改爲完成狀態。

我有2個表,這裏是它們的一般結構。請注意0​​是一個從google_sort_backlink_domains返回idgoogle_sort_tablekey列的外鍵。

google_sort_tablekey:

  • id - 主鍵,索引列
  • unique_id - 用作唯一標識符這個工具運行的唯一哈希
  • processing_completed - 布爾標誌處理競速賽當設置爲1

google_sort_ba cklink_domains:

  • id - 主鍵,索引列
  • tablekey_id - 外鍵google_sort_tablekey
  • checked - 布爾標誌設置爲1,當鏈接被捲曲,然後
  • link_found - 布爾標誌設置如果在第一次或第二次檢查期間發現反向鏈接,則將其設爲1
  • link_href - 字符串,鏈接到頁面

這裏是一個什麼樣的數據可能看起來像

google_sort_tablekey: 
id  unique_id  processing_completed 
23  35799756448  1 
24  78698778978  0 

google_sort_backlink_domains: 
id  tablekey_id  checked  link_found  link_href 
11  23    1   0    http://www.website.com/1... 
12  24    0   0    http://www.website.com/2... 
13  23    1   1    http://www.website.com/3... 
14  24    1   1    http://www.website.com/4... 
15  24    1   1    http://www.website.com/5... 
16  24    0   0    http://www.website.com/6... 

一個非常小的例子這裏是我的查詢時,我處理的100,000行的數據集需要的方式來長時間,但是工作。我添加了空間來幫助提高可讀性,並且我還在24位ID中進行了硬編碼,這將在生產中設置爲變量。

SELECT `processing_completed` AS complete, 

ROUND((SELECT((SUM(IF((`link_found` = 1 OR `checked` >= (SELECT MAX(`checked`) 
    FROM `google_sort_backlink_domains` WHERE `tablekey_id` = 24)), 1, 0))/SUM(1))*100) AS percent 
FROM `google_sort_backlink_domains` WHERE `tablekey_id` = 24), 1) AS percent, 

CASE WHEN `processing_completed` = 1 THEN 3 WHEN MAX(`checked`) = 0 THEN 1 ELSE MAX(`checked`) END AS current_step, 

(SELECT COUNT(1) FROM `google_sort_backlinks` WHERE `tablekey_id` = 24) AS total_rows, 

(SELECT COUNT(1) FROM `google_sort_backlink_domains` WHERE `tablekey_id` = 24) AS unique_domains, 

(SELECT COUNT(1) FROM `google_sort_backlink_domains` WHERE `tablekey_id` = 24 AND `link_found` = 1) AS live_rows, 

(SELECT COUNT(1) FROM `google_sort_backlink_domains` WHERE `tablekey_id` = 24 
AND `checked` >= (
SELECT CASE WHEN `processing_completed` = 1 THEN 3 WHEN MAX(`checked`) = 0 THEN 1 ELSE MAX(`checked`) END FROM `google_sort_backlink_domains` WHERE `tablekey_id` = 24 
)) AS dead_rows 

FROM `google_sort_tablekey` AS tablekey 
JOIN `google_sort_backlink_domains` AS domain ON domain.tablekey_id = tablekey.id 
WHERE domain.tablekey_id = 24 

誰能幫我做我的查詢更加有效,以便它可以在google_sort_backlink_domains表處理超過10萬行?謝謝,麻煩您了!

+2

第一:您的表格是否正確編制索引?第二:使用'explain select ...'來檢查執行計劃並檢查哪些文件需要編制索引。請參閱參考手冊:http://dev.mysql.com/doc/refman/5.5/en/using-explain.html – Barranka 2013-04-04 17:36:34

+0

是的,我使用索引,但現在我沒有一個在選中的列。我現在補充說,謝謝提醒。 – RachelC 2013-04-04 17:38:29

+0

查詢需要132.4556秒,其索引爲:( – RachelC 2013-04-04 17:53:51

回答

1

嘗試更像這樣的東西,其中更多的「常量」計算放置在變量中,子查詢用集合替換。

SET @id = 24; 
SET @den = (SELECT SUM(1) FROM google_sort_backlink_domains); 
SET @max = (SELECT MAX(checked) FROM google_sort_backlink_domains WHERE [email protected]); 
SET @n = (SELECT 
       CASE 
        WHEN processing_completed = 1 THEN 3 
        WHEN MAX(checked) = 0 THEN 1 
        ELSE MAX(checked) END 
      FROM google_sort_backlink_domains WHERE [email protected]); 

SELECT 
    processing_completed AS complete, 
    SUM(IF(link_found=1 OR checked>[email protected], 1, 0))/@den AS percent, 
    CASE 
     WHEN processing_completed=1 THEN 3 
     WHEN MAX(checked)=0 THEN 1 
     ELSE MAX(checked) 
    END AS current_step, 
    COUNT(back.id) AS total_rows, 
    COUNT(domain.id) AS unique_domains, 
    SUM(link_found) AS live_rows, 
    SUM(IF(checked>= @n), 1, 0) AS dead_rows 
FROM google_sort_tablekey AS tablekey 
JOIN google_sort_backlink AS back ON back.tablekey_id = tablekey.id 
JOIN google_sort_backlink_domains AS domain ON domain.tablekey_id = tablekey.id 
WHERE domain.tablekey_id = @id 
GROUP BY processing_completed 
+0

Im在'','1'附近的末尾附近得到一個SQL語法錯誤, 0)作爲dead_rows從google_sort_tablekey作爲tablekey JOIN google_sort_'在第12行 - 我試圖調試它,但沒有運氣呢。 NEVERMIND:這是一個帶有表名的錯字。 – RachelC 2013-04-04 18:56:12