我需要在多个条件下运行查询,这将产生大型数据集。尽管所有条件都很简单,但我需要关于速度优化方面的 2 个问题的建议:
1) 如果我需要在过去 10 年的每年 4 月 1 日至 6 月 20 日之间运行这些查询,据我所知,我有 2 个选择:
一个。运行查询 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;
}
单次运行查询,但是查询将按 DayOfYear 进行比较(因此每个日期都必须通过查询转换为 DayOfYear)
$start = Date("z", strtotime("2015-04-01")) + 1;
$end = Date("z", strtotime("2015-06-20")) + 1;
$result = mysql_query("....... WHERE .... AND DAYOFYEAR(`event_date`) BETWEEN $start AND $end");
我知道闰年与其他年份的天数有 1 天的差异,但我可以接受。我感觉 1.b 更优化了,只是想验证一下。
2) 我有一个包含 2 个子查询的大型查询。当我想按日期限制结果时,我应该把条件放在子查询里面还是外面?
一个。内部子查询意味着它必须验证条件两次
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`
外部子查询意味着它将验证一次,但必须加入更大的数据集(为此我需要设置 SQL_BIG_SELECTS = 1)
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`
同样,我认为 2.a 更优化,但请求您的建议。
谢谢
最佳答案
(1) 当 SQL 引擎可以利用 event_date
上的索引时,使用 event_date BETWEEN $start AND $end
运行查询 10 次会更快。这可能很重要,但这取决于查询的其余部分。
此外,由于您要对整个数据集进行排序,因此运行 10 个查询可能会快一些。那是因为排序是 O(n log(n)),这意味着对更大的数据集进行排序需要更长的时间。例如,对 100 行进行排序可能需要 X 个时间单位。对 1000 行进行排序可能需要 X * 10 * log(10) 个时间单位。但是,对 100 行排序 10 次只需要 X * 10(这是为了解释目的)。
(2) 如果可以避免在 MySQL 中使用子查询,则不要使用子查询。子查询被具体化,这增加了额外的开销。另外,他们随后会阻止使用索引。如果需要使用子查询,尽可能在子查询中过滤数据。这减少了需要存储的数据。
关于php - SQL 查询优化 - 多查询或 DAYOFYEAR()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32162580/