Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.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 SQL查询优化-多查询或DAYOFYEAR()?_Php_Mysql - Fatal编程技术网

Php SQL查询优化-多查询或DAYOFYEAR()?

Php SQL查询优化-多查询或DAYOFYEAR()?,php,mysql,Php,Mysql,我需要在几个条件下运行查询,这些条件将导致大数据集。鉴于所有条件都是直截了当的,我需要关于速度优化方面的两个问题的建议: 1) 如果我需要在过去10年中每年的4月1日至6月20日期间运行这些查询,我有两种选择: a。运行查询10次 $year = 2015; $start_month_date = "-04-01"; $end_month_date = "-06-20"; for($i=0;$i<10;$i++){ $start = $year.$start_month_date;

我需要在几个条件下运行查询,这些条件将导致大数据集。鉴于所有条件都是直截了当的,我需要关于速度优化方面的两个问题的建议:

1) 如果我需要在过去10年中每年的4月1日至6月20日期间运行这些查询,我有两种选择:

a。运行查询10次

$year = 2015;
$start_month_date = "-04-01";
$end_month_date = "-06-20";
for($i=0;$i<10;$i++){
  $start = $year.$start_month_date;
  $end = $year.$start_month_date;
  $result = mysql_query("....... WHERE .... AND `event_date` BETWEEN $start AND $end");
  // PUSH THE RESULT TO AN ARRAY
  $year = $year - 1;
}
我知道闰年的天数与其他年份相差一天,但我可以接受。我感觉1.b更优化,只是想验证一下

2) 我有一个包含两个子查询的大查询。当我想按日期限制结果时,我应该将条件放在子查询的内部还是外部

a。内部子查询意味着它必须两次验证条件

SELECT X.a,X.b,Y.c FROM 
(SELECT * FROM mytable WHERE `event_date` BETWEEN '$startdate' AND '$enddate' AND `case` = 'AAA' AND .......) X
(SELECT * FROM mytable WHERE `event_date` BETWEEN '$startdate' AND '$enddate' AND `case` = 'BBB' AND .......) Y
WHERE X.`event_date` = Y.`event_date` AND ........... ORDER BY `event_date`
b。外部子查询意味着它将验证一次,但必须加入一个更大的数据集(我需要为其设置SQL\u BIG\u SELECTS=1)

同样,在我看来2.a更为优化,但需要您的建议

谢谢(1)当SQL引擎可以利用
事件日期
上的索引时,使用$start和$end之间的
事件日期运行查询10次会更快。这可能很重要,但这取决于查询的其余部分

另外,由于您要对整个数据集进行排序,因此运行10个查询可能会快一点。这是因为排序是O(n log(n)),这意味着对较大的数据集进行排序需要更长的时间。例如,对100行进行排序可能需要X个时间单位。对1000行进行排序可能需要X*10*log(10)个时间单位。但是,对100行进行10次排序只需要X*10(这是为了解释)


(2) 如果可以在MySQL中避免子查询,请不要使用它们。子查询被具体化,这增加了额外的开销。此外,它们还阻止使用索引。如果需要使用子查询,请在子查询中尽可能多地过滤数据。这减少了需要存储的数据。

我假设您在10年内有很多行,否则这不会是什么问题

现在最好的办法是对您计划使用的不同查询做一些解释,这可能会告诉您它可以使用哪个索引,因为目前我们不知道它们(您没有发布表的结构)

1.b。在where子句中使用一个函数,这样会很糟糕,因为它不能使用日期索引(假设有索引)。这将读取整个表

您可以做的一件事是让数据库使用UNION将10个查询的结果集连接在一起。Mysql将加入结果而不是php。。。(见附件)


正如戈登所说,尽可能多地过滤数据。不过,您可以使用EXPLAIN,而不是盲目尝试该选项,数据库将帮助您决定哪一个选项最有意义。

非常感谢。。这就是为什么我总是在这里接受建议,所以。。。只是一些确认:(1)基本上查询与示例2相同,有两个子查询。我有3个字段的条件,除了event_date,我只使用额外的条件:case='A'和month='JUL',诸如此类的东西。所有这3个字段都在mysql数据库表中建立索引。因此,我将按照您的建议使用10个查询方法。(2)因此,我将在子查询(如果我需要使用它们)中尽可能多地放置条件,而不是将它们放在连接数据集的末尾。如果您具有相等条件,则在
案例、月份、事件_日期
上的索引将是一个很好的索引选择。谢谢。。。我确实有这3方面的索引。。但是,月份和大小写是相等条件的,事件的日期是以BETWEENokay为界的,基本上我需要在3个字段上设置条件,并且所有这3个字段都被索引。非常感谢。。你们两个都同意相同的方法(其中一个与我的想法相反:)。所以我会按照你们的经验建议,我记得mysql有时在日期范围超过30天(即mysql 5.1)时不使用索引,所以即使这看起来是最好的索引,它也会做一些意想不到的事情。因此,您应该检查它使用的索引。它将无法使用所有3:)
SELECT X.a,X.b,Y.c FROM 
(SELECT * FROM mytable WHERE `event_date` BETWEEN '$startdate' AND '$enddate' AND `case` = 'AAA' AND .......) X
(SELECT * FROM mytable WHERE `event_date` BETWEEN '$startdate' AND '$enddate' AND `case` = 'BBB' AND .......) Y
WHERE X.`event_date` = Y.`event_date` AND ........... ORDER BY `event_date`
SELECT X.a,X.b,Y.c FROM 
(SELECT * FROM mytable WHERE `case` = 'AAA' AND .......) X
(SELECT * FROM mytable WHERE `case` = 'BBB' AND .......) Y
WHERE X.`event_date` = Y.`event_date` AND X.`event_date` BETWEEN '$startdate' AND '$enddate' AND ........... ORDER BY `event_date`