Liz*_*ard 6 php mysql optimization
我有以下内容,当它自己运行时非常快,但是当我执行此操作时,许多entity_id
查询开始花费的时间越来越长(循环是一个PHP foreach),例如此查询只需要0.078但相同的查询循环中的另一个实体需要2.1秒,查询似乎越慢越慢,我放入循环的实体越多.为什么是这样?以及如何改进/优化查询?
foreach($entity_ids as $entity_id) {
SELECT COUNT(*) as prev, DATE_FORMAT(`created`, '%Y%m%d') AS date_group
FROM articles_entities
WHERE entity_id = '$entity_id'
AND `created` >= DATE_SUB(CURDATE(), INTERVAL 10 DAY)
GROUP BY date_group
// store result
}
Run Code Online (Sandbox Code Playgroud)
我有以下表结构:
CREATE TABLE `articles_entities` (
`id` CHAR(36) NOT NULL,
`article_id` CHAR(36) NOT NULL,
`entity_id` CHAR(36) NOT NULL,
`created` DATETIME DEFAULT NULL,
`modified` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `article_id` (`article_id`),
KEY `entity_id` (`entity_id`),
KEY `created` (`created`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
它看起来像你有一个ID数组,然后想从你的表中拉出记录(以你的语句控制的方式),其中ID字段匹配其中一个数组值.
而不是在PHP中使用LOOP来运行多个SQL语句,最好的做法是构建一个主语句,然后使用PHP来处理结果.您可以使用SQL IN语句完成此操作:
// where $entity_ids is an array eg 1,2,3,4,5
$sql="SELECT entity_id AS 'alt_entity_id', COUNT(entity_id) as prev, DATE_FORMAT(`created`, '%Y%m%d') AS 'date_group'
FROM articles_entities
WHERE entity_id IN ".implode(",",$entity_ids)."
AND `created` >= DATE_SUB(CURDATE(), INTERVAL 10 DAY)
GROUP BY date_group, entity_id";
// you may wish to revese the group fields, as you require, you may also wish to change the count field to date_group, depending on what you wish to be counted
Run Code Online (Sandbox Code Playgroud)
这将针对您拥有的所有id值运行原始查询一次,按日期和传递的id值进行分组.然后,您可以使用PHP从返回的结果集中筛选出特定id的结果.
这比循环执行查询产生的开销更有效.
您返回的结果集将类似于:
entity_id | count(entity_id) | date_group
----------|------------------|------------
1 | 3 | 2010-04-01
1 | 3 | 2010-03-01
1 | 3 | 2010-02-01
2 | 2 | 2010-01-01
2 | 2 | 2010-02-01
3 | 1 | 2010-06-01
4 | 2 | 2010-06-01
4 | 2 | 2010-02-01
Run Code Online (Sandbox Code Playgroud)