Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php mysql查询速度优化_Php_Mysql_Optimization - Fatal编程技术网

Php mysql查询速度优化

Php mysql查询速度优化,php,mysql,optimization,Php,Mysql,Optimization,我有以下几点,单独运行时速度非常快,但当我对许多实体_id执行此操作时,查询开始花费越来越长的时间(循环是一个PHP foreach),例如,此查询只需要0.078秒,但循环中不同实体上的相同查询最多需要2.1秒,我在循环中放入的实体越多,查询似乎越慢。为什么会这样?如何改进/优化查询? foreach($entity_ids as $entity_id) { SELECT COUNT(*) as prev, DATE_FORMAT(`created`, '%Y%m%d') AS dat

我有以下几点,单独运行时速度非常快,但当我对许多
实体_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
}
我有以下表格结构:

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;

我不知道从何处获取循环的实体值,但在循环中执行此查询总是会带来很大的性能开销。如果您是从以前的SQL查询中获取实体ID,那么重构SQL以将初始查询与循环查询连接起来,以便在单个SQL查询中返回所需的所有数据可能更有意义。

您处理的实体大概有多少


您是否可以将所需的实体插入一个单独的表中并进行连接,而不是进行多个查询

将所有ID放入一个数组,将其连接成一个字符串,并使用“where in”以优化的方式获取详细信息

$enitityIDS = array();
    foreach($entity_ids as $entity_id) {
       $enitityIDS[]=$entity_id;
    }
    $entityIDString = join(",",$enitityIDS);
那就做吧

SELECT COUNT(*) as prev, DATE_FORMAT(`created`, '%Y%m%d') AS date_group 
    FROM articles_entities 
    WHERE entity_id in (".$entityIDString.")
    AND `created` >= DATE_SUB(CURDATE(), INTERVAL 10 DAY) 
    GROUP BY date_group, entity_id

最佳方式

在我看来,您有一个ID数组,然后希望从ID字段与其中一个数组值匹配的表中提取记录(以语句控制的方式)

最好的方法不是在PHP中使用循环来运行多个SQL语句,而是构建一个主语句,然后使用PHP来处理结果。您可以使用SQL语句完成此操作:

    // 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
这将对您拥有的所有id值运行一次原始查询,并按日期和传递的id值分组。然后,您可以使用PHP从返回的resultset中过滤出特定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

$entity_ID来自何处?我首先从同一个表中选择了符合特定条件(不同日期范围)的文章,并返回了其名称entities@Lizard-我的观点是,应该可以将第一个select与循环select相结合:如果您发布两个查询(以及任何其他相关的表结构),我们可能可以制定一个查询,这意味着您不必在循环中执行一系列查询。别忘了,您还需要按id字段对查询进行分组,否则in子句的结果无法区分。答案中唯一缺少的是选择,实体id为alt_entity_id,因为我可以计算出每个实体是哪个实体(注意,我不能只选择实体id,因为它给出了错误的结果。(我还必须交换分组。如果你更新你的答案,我将接受它。)。