MySQL 非常长的查询
MySQL very long queries
我有一个相当大的数据库(800+Mb 转储文件)导入到我的本地服务器。它是来自 的 Wordpress 数据库,我需要提取某些帖子。里面大约有 160000 个帖子。
目前我正在测试 MySql Workbench 运行 简单的 JOIN 查询,这需要很多时间,实际上太长了 Workbench 停止处理。
这是一个例子:
SELECT
COUNT(*)
FROM wp_posts
LEFT JOIN wp_term_relationships
ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN wp_term_taxonomy
ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
LEFT JOIN wp_terms
ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE wp_terms.term_id = 195;
运行 超过 600 秒。
这是一个 wordpress 数据库模式:
当然有可能我只是不擅长 SQL,不是我的领域...
如果您在用于连接的列上有所有索引(wp_posts.ID、wp_term_relationships.object_id 等),这应该不是问题,查询应该在不到 1 秒内执行( 1 秒也很多)。
此外,队列中可能正在等待其他查询(锁定),因此您应该将其添加到这些查询中:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT
COUNT(*)
FROM
wp_posts
LEFT JOIN
wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN
wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
LEFT JOIN
wp_terms ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE
wp_terms.term_id = 195;
COMMIT ;
在 workbench 中创建索引。我可以在这里看到您在每个 table 上加入 ID,因此因为这些是 ID 列,所以它们应该是主键,并在它们上创建 UNIQUE 聚簇索引。
如果您真的只是 运行 计数,您可以通过以下方式获得结果:
SELECT COUNT(*)
FROM wp_term_relationships wtr
JOIN wp_term_taxonomy wtt
ON wtt.term_taxonomy_id = wtr.term_taxonomy_id
WHERE wtt.term_id = 195;
您不需要这些记录所附的强制性 wp_terms
或 wp_posts
记录中的信息。
您也不需要 LEFT JOIN
,因为您正在丢弃具有 WHERE
条件的 NULL
元组。
至于速度,我建议 运行 以 EXPLAIN
为前缀的查询,并检查是否正确索引了所有内容并且正在使用这些索引。
我有一个相当大的数据库(800+Mb 转储文件)导入到我的本地服务器。它是来自 的 Wordpress 数据库,我需要提取某些帖子。里面大约有 160000 个帖子。
目前我正在测试 MySql Workbench 运行 简单的 JOIN 查询,这需要很多时间,实际上太长了 Workbench 停止处理。
这是一个例子:
SELECT
COUNT(*)
FROM wp_posts
LEFT JOIN wp_term_relationships
ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN wp_term_taxonomy
ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
LEFT JOIN wp_terms
ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE wp_terms.term_id = 195;
运行 超过 600 秒。
这是一个 wordpress 数据库模式:
当然有可能我只是不擅长 SQL,不是我的领域...
如果您在用于连接的列上有所有索引(wp_posts.ID、wp_term_relationships.object_id 等),这应该不是问题,查询应该在不到 1 秒内执行( 1 秒也很多)。
此外,队列中可能正在等待其他查询(锁定),因此您应该将其添加到这些查询中:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT
COUNT(*)
FROM
wp_posts
LEFT JOIN
wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
LEFT JOIN
wp_term_taxonomy ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
LEFT JOIN
wp_terms ON wp_term_taxonomy.term_id = wp_terms.term_id
WHERE
wp_terms.term_id = 195;
COMMIT ;
在 workbench 中创建索引。我可以在这里看到您在每个 table 上加入 ID,因此因为这些是 ID 列,所以它们应该是主键,并在它们上创建 UNIQUE 聚簇索引。
如果您真的只是 运行 计数,您可以通过以下方式获得结果:
SELECT COUNT(*)
FROM wp_term_relationships wtr
JOIN wp_term_taxonomy wtt
ON wtt.term_taxonomy_id = wtr.term_taxonomy_id
WHERE wtt.term_id = 195;
您不需要这些记录所附的强制性 wp_terms
或 wp_posts
记录中的信息。
您也不需要 LEFT JOIN
,因为您正在丢弃具有 WHERE
条件的 NULL
元组。
至于速度,我建议 运行 以 EXPLAIN
为前缀的查询,并检查是否正确索引了所有内容并且正在使用这些索引。