优化包含子选择的MySQL查询

时间:2013-04-04 17:33:24

标签: mysql sql

我有一个可以被描述为我需要优化的大胖MySQL查询。查询的作用是选择与反向链接处理相关的数据。

通过反向链接处理,我的意思是大约有100,000个链接被添加到数据库中。链接被选中并分批卷曲,寻找我网站的反向链接。

我在此查询中选择的信息是:

  • complete - 已完成处理(bool 1或0)
  • current_step - 我们在(1,2或3)
  • 中有3个步骤
  • percent - 我在这个步骤中做了多少百分比(0.0-100.0)
  • total_rows - 数据库中所有行的完整计数 表密钥id(整数)
  • live_rows - 使用我的网页的实时反向链接找到的链接数量(整数)
  • dead_rows - 找到的没有反向链接(整数)的链接数

注意:通过查看checked列的MAX()值来计算当前步长。如果找不到链接,我们会检查链接两次。因此,当工具首次开始运行时,所有checked值都设置为零(因为处理尚未开始),因此我们希望当前步骤为步骤1.然后我们处理所有行和所有{{ 1}}值设置为1,百分比将返回为步骤1的100.00,程序然后开始仔细检查第一次发现死的链接。当第二次检查时,一些行被设置为2,因此MAX(已选中)返回第二步的2。完成第二步后,程序会将checked列更改为1,然后返回3作为完成的当前步骤。我们返回3因为它导致UI更改为完成状态。

我有两张桌子,这是他们的一般结构。请注意,processing_complete是从tablekey_id返回google_sort_backlink_domainsid列的外键。

google_sort_tablekey:

  • google_sort_tablekey - 主键,索引列
  • id - 用作此工具的唯一标识符的唯一哈希
  • unique_id - 处理竞争时bool标志设置为1

google_sort_backlink_domains:

  • processing_completed - 主键,索引列
  • id - google_sort_tablekey的外键
  • tablekey_id - 当链接卷曲然后
  • 时,bool标志设置为1
  • checked - 如果在第一次或第二次检查中发现反向链接,则bool标志设置为1
  • link_found - 字符串,指向页面的链接

这是一个非常小的数据示例

link_href

这是我的查询,但是当我处理100,000行的数据集时,它需要很长时间。我添加了空格来帮助提高可读性,而且我还在24的id中硬编码,这将在生产中设置变量。

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...

任何人都可以帮我提高查询效率,以便在google_sort_backlink_domains表中处理超过100,000行吗?拜托,谢谢!

1 个答案:

答案 0 :(得分: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 tablekey_id=@id);
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 tablekey_id=@id);

SELECT 
    processing_completed AS complete,
    SUM(IF(link_found=1 OR checked>=@max, 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