查询优化,选择调用函数

时间:2013-11-21 15:34:13

标签: mysql

考虑一个大表,下面哪个更快?

两个查询都将选择time大于当前时间的行。

NOW()子句中调用WHERE

SELECT          *
FROM            myTable
WHERE           time > NOW()

在子查询中结束对NOW()的调用:

SELECT          *
FROM            myTable
LEFT JOIN       (
                    SELECT NOW() AS currentTime
                ) AS currentTimeTable ON TRUE                   
WHERE           time > currentTime

2 个答案:

答案 0 :(得分:2)

  

“两个查询都会选择时间不超过10天的行。”

抱歉,您的查询不正确。我在MySQL中测试了它并获得了这个:

mysql> SELECT DATE(NOW() - 10);
+------------------+
| DATE(NOW() - 10) |
+------------------+
| 2013-11-21       |
+------------------+

21.11.2013 - 是当前日期而不是现在()减去10天。

您应该使用DATE_SUB函数:

mysql> SELECT DATE_SUB( NOW(), INTERVAL 10 DAY );
+-------------------------------------+
| DATE_SUB( NOW() , INTERVAL 10 DAY ) |
+-------------------------------------+
| 2013-11-11 19:40:38                 |
+-------------------------------------+

这样的事情:

SELECT *
FROM   `myTable`
WHERE  `time` > DATE_SUB(NOW(), INTERVAL 10 DAY );

以下是对两种查询类型的分析:

EXPLAIN 
SELECT 
    *
FROM
    users
WHERE
    created > now();

测试数据

我在Drupal安装中尝试过用户表。

的MySQL> EXPLAIN SELECT * 来自用户 WHERE创建< NOW();

+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | users | range | created       | created | 4       | NULL |    1 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)



EXPLAIN
SELECT 
    *
FROM
    users
LEFT JOIN (
                    SELECT NOW() AS currentTime
          ) AS tbl ON TRUE
WHERE created < tbl.currentTime;

+----+-------------+------------+--------+---------------+---------+---------+------+------+----------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows | Extra          |
+----+-------------+------------+--------+---------------+---------+---------+------+------+----------------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL |    1 |                |
|  1 | PRIMARY     | users      | range  | created       | created | 4       | NULL |    1 | Using where    |
|  2 | DERIVED     | NULL       | NULL   | NULL          | NULL    | NULL    | NULL | NULL | No tables used |
+----+-------------+------------+--------+---------------+---------+---------+------+------+----------------+
3 rows in set (0.02 sec)

结论

显然,1-st查询更好,因为它不需要创建任何临时表。即使使用我的小样本数据,执行第一个查询也需要0秒,而第二个查询则需要0,02秒。

答案 1 :(得分:0)

1)当您谈论日期优化时,使用timestamps是可行的方法。

2)我建议不要调用函数来进行数学运算,而是为每一行创建另一列及其时间戳

3)正如PeeHaa this thread所说的那样:«当谈论哪一段代码更快(在你的OP中)时,你谈论的是微优化,而你真的不应该这样做不得不担心。 ☺

真正的问题是哪一段代码是:更好的可维护性,可读性,可理解性。 »

我理解什么是非常大的数据库管理,但是一旦优化了索引和数据类型,您很可能就足够了。