优化昂贵的 php 查询/子查询
Posted
技术标签:
【中文标题】优化昂贵的 php 查询/子查询【英文标题】:optimize expensive php query/subquery 【发布时间】:2013-07-10 19:49:55 【问题描述】:我有一个包含 3 列的表:submission_id、column_id、data。每个submission_id 有25 列和数据值。
我有一个页面显示所有提交,其中 column_id = 16 和 data = ('' or 0)。为此,我使用子查询来获取我需要的所有不同的submission_id,然后获取主查询中的所有列。我的查询是:
SELECT sid,cid,data FROM webform_submitted_data WHERE sid in(select distinct sid from webform_submitted_data where cid=16 and data in (' ',0)) ORDER BY sid ASC
表变大了,现在从 php 运行查询需要 30-40 秒(虽然从 mysql 只需要 1.0e-6 秒)这不是 PHP 开销,我使用 mysqld-slow.log 文件检查,我得到以下信息:
我还尝试在 PHP 中运行解释 ![解释]:(http://i.imgur.com/692eyHf.png)
还有一件事,这个页面更新了当前提交,并在 column_id 16 中放置了一个 ID 值,当它重新加载时,它会从页面中删除。没有更新的重新加载需要不到一秒的时间,但是当我们需要更新 100 条记录时,它每次都会重建缓存。
任何想法将不胜感激。
【问题讨论】:
我的 SQL 有点生疏,但我没有看到那里需要子查询。你所拥有的与SELECT sid,cid,data FROM webform_submitted_data WHERE cid=16 and data in (' ',0) ORDER BY sid ASC
不完全一样吗?
你是如何在 PHP 中运行查询的?您决定使用的 API 是否具有准备 SQL 的“准备”方法?这可能会有所帮助……也许。 (我猜)
具有 cid=16 的 where 子句不允许其他 cid 出现在结果中
@brett_m - 啊,谢谢!
【参考方案1】:
EXPLAIN 报告的DEPENDENT SUBQUERY
成本最高。这意味着它为外部查询中的每个不同的 sid 执行一次子查询。此成本的开销与 180000 多行中不同 sid 值的数量有关。
您可以尝试此查询以确保子查询仅执行一次。根据您的说明,它可能需要将结果存储在临时表中,但该临时表将只有大约 7 行。
SELECT d1.sid, d1.cid, d1.data
FROM webform_submitted_data AS d1
INNER JOIN (
SELECT DISTINCT sid FROM webform_submitted_data
WHERE cid=16 AND data IN (' ',0)) AS d2 USING (sid)
ORDER BY d1.sid ASC
【讨论】:
以上是关于优化昂贵的 php 查询/子查询的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 子查询优化 - where not in(子查询)