Answers:
使用DATE
和CURDATE()
SELECT * FROM `table` WHERE DATE(`timestamp`) = CURDATE()
我想使用DATE
仍然使用INDEX。
Using where; Using index
?
timestamp
(和date
我的情况一样)是MySQL保留字
如果要使用索引并且查询不执行表扫描:
WHERE timestamp >= CURDATE()
AND timestamp < CURDATE() + INTERVAL 1 DAY
为了显示这对实际执行计划的影响,我们将使用SQL-Fiddle(一个非常有用的网站)进行测试:
CREATE TABLE test --- simple table
( id INT NOT NULL AUTO_INCREMENT
,`timestamp` datetime --- index timestamp
, data VARCHAR(100) NOT NULL
DEFAULT 'Sample data'
, PRIMARY KEY (id)
, INDEX t_IX (`timestamp`, id)
) ;
INSERT INTO test
(`timestamp`)
VALUES
('2013-02-08 00:01:12'),
--- --- insert about 7k rows
('2013-02-08 20:01:12') ;
现在让我们尝试2个版本。
版本1与 DATE(timestamp) = ?
EXPLAIN
SELECT * FROM test
WHERE DATE(timestamp) = CURDATE() --- using DATE(timestamp)
ORDER BY timestamp ;
说明:
ID SELECT_TYPE TABLE TYPE POSSIBLE_KEYS KEY KEY_LEN REF
1 SIMPLE test ALL
ROWS FILTERED EXTRA
6671 100 Using where; Using filesort
它过滤所有(6671)行,然后进行文件排序(这不成问题,因为返回的行很少)
版本2 timestamp <= ? AND timestamp < ?
EXPLAIN
SELECT * FROM test
WHERE timestamp >= CURDATE()
AND timestamp < CURDATE() + INTERVAL 1 DAY
ORDER BY timestamp ;
说明:
ID SELECT_TYPE TABLE TYPE POSSIBLE_KEYS KEY KEY_LEN REF
1 SIMPLE test range t_IX t_IX 9
ROWS FILTERED EXTRA
2 100 Using where
它对索引使用范围扫描,然后仅从表中读取相应的行。
INDEX t_IX (timestamp, id)
可能是(应该?)INDEX t_IX (timestamp)
,因为索引中隐含了主键。还是有我不理解的原因?我在sql-fiddle中进行了尝试,看到了相同的(更好的)执行计划
id
(因为它是PK,因此是表的聚集索引)(无论如何)都将附加在索引中。因此,显式添加它没有什么坏处(它可能会遇到一些优化器盲点)。在这种情况/查询中,这当然是不相关的。
timestamp < CURDATE() + INTERVAL 1 DAY
有必要?
SELECT * FROM `table` WHERE timestamp >= CURDATE()
它更短,不需要使用“ AND timestamp <CURDATE()+ INTERVAL 1 DAY”
因为CURDATE()总是返回当前日期
我认为这可能是最简单的:
SELECT * FROM `table` WHERE `timestamp` like concat(CURDATE(),'%');
或者,您可以使用CURRENT_DATE替代方法,结果相同:
SELECT * FROM yourtable WHERE created >= CURRENT_DATE
在Visual Studio 2017上,使用内置数据库进行开发时,我在使用当前给定的解决方案时遇到了问题,我不得不更改代码以使其起作用,因为它引发了DATE()不是内置函数的错误。
这是我的解决方案:
where CAST(TimeCalled AS DATE) = CAST(GETDATE() AS DATE)