我有一个可以被描述为我需要优化的大胖MySQL查询。查询的作用是选择与反向链接处理相关的数据。
通过反向链接处理,我的意思是大约有100,000个链接被添加到数据库中。链接被选中并分批卷曲,寻找我网站的反向链接。
我在此查询中选择的信息是:
complete
- 已完成处理(bool 1或0)current_step
- 我们在(1,2或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_domains
中id
列的外键。
google_sort_tablekey:
google_sort_tablekey
- 主键,索引列id
- 用作此工具的唯一标识符的唯一哈希unique_id
- 处理竞争时bool标志设置为1 google_sort_backlink_domains:
processing_completed
- 主键,索引列id
- google_sort_tablekey的外键tablekey_id
- 当链接卷曲然后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行吗?拜托,谢谢!
答案 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