优化SQL查询


Optimizing SQL query

我必须在数据库中获得两个日期之间有publish_date的所有条目。所有日期都存储为整数,因为日期是UNIX TIMESTAMP格式。以下查询工作完美,但它需要"太长"。它返回10到20个小时之前的所有条目。

SELECT * FROM tbl_post WHERE published <  (UNIX_TIMESTAMP(NOW())-864000) 
AND published> (UNIX_TIMESTAMP(NOW())-1728000)

有什么方法可以优化这个查询吗?如果我没有弄错的话,它在每个条目上调用NOW()和UNIX_TIMESTAMP。我认为将这2个重复函数的结果保存到mysql @var使比较更快,但事实并非如此。我运行的第二个代码是:

SET @TenDaysAgo = UNIX_TIMESTAMP(NOW())-864000;
SET @TwentyDaysAgo = UNIX_TIMESTAMP(NOW())-1728000;
SELECT * FROM tbl_post WHERE fecha_publicado <  @TenDaysAgo 
AND fecha_publicado > @TwentyDaysAgo;

另一个令人困惑的事情是PHP不能通过mysql_query()运行上面的查询;?!

如果你对这个问题有任何意见,我们将非常欢迎。

卢卡

确保已发布的索引。并确保它正在被使用。

EXPLAIN SELECT * FROM tbl_post WHERE published <  (UNIX_TIMESTAMP(NOW())-864000)  AND published> (UNIX_TIMESTAMP(NOW())-1728000)

应该是一个很好的开始,可以看到查询中发生了什么。添加索引:

ALTER TABLE tbl_post ADD INDEX (published)

PHP的mysql_query函数(假设你使用的是这个)每个字符串只能接受一个查询,所以它不能执行第二个查询中的三个查询。

我建议将这些东西移到存储过程中,并从PHP调用。

至于优化,设置这些变量与您将为查询获得的优化差不多。您需要对每一行进行比较,并且设置一个变量可以提供对下限和上限的最快访问时间。

索引表的一个改进,而不是查询本身,是围绕fecha_publicado聚集索引,以允许MySQL智能地处理该值范围的查询。您可以通过将fecha_publicado设置为表的PRIMARY KEY来轻松实现这一点。

要检查的明显事情是,是否有发布日期的索引,以及它是否被使用?

优化的方法是根据日期范围(每周似乎适合您的查询)对发布的键上的表tbl_post进行分区。这是MySQL, PostgreSQL, Oracle, Greenplum等的一个特性。

这将允许查询优化器将查询限制到更窄的数据集。

我同意BraedenP的观点,存储过程在这里是合适的。如果您不能使用或确实不想使用,您总是可以在PHP端生成日期,但它们可能与数据库不完全匹配,除非您将它们同步。

你也可以做得更快,因为3个单独的查询可能。查询开始数据,查询结束日期,然后将这些值用作目标查询的输入。