2011-04-25 191 views
1

我必须获取在两个日期之间具有publish_date的数据库中的所有条目。所有日期都以整数形式存储,因为日期采用UNIX TIMESTAMP格式... 以下查询完美无缺,但需要“太长时间”。它会返回10到20之前的所有条目。优化SQL查询

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

有没有什么办法可以优化这个查询?如果我没有弄错,它会调用evey条目上的NOW()和UNIX_TIMESTAMP。我认为将这两个重复函数的结果保存到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()运行bove查询; ?!

请,如果你对这个问题的任何意见会比欢迎:)

卢卡更多

+0

请注意,NOW()是一个常量表达式,它表示语句何时开始执行。所以MySQL没有理由不能将'UNIX_TIMESTAMP(NOW()) - 864000'转换成一个常量表达式。 (我不知道它是否......只是它很容易就可以。) – Matthew 2011-04-25 17:12:09

回答

2

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

我建议将这些东西移动到stored procedure,然后从PHP调用它。

至于优化,设置这些变量是关于你的查询优化。您需要对每一行进行比较,并且设置一个变量为下限和上限提供了最快的访问时间。

索引表中的一项改进,而不是查询本身,可以将索引围绕fecha_publicado进行聚类,以允许MySQL智能地处理该范围值的查询。通过将fecha_publicado设置为表格的PRIMARY KEY,可以轻松完成此操作。

0

方式来优化将根据日期范围的公布键分区表tbl_post(每周似乎是适当的查询)。这是一个可用于MySQL,PostgreSQL,Oracle,Greenplum等的功能。

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

+0

分区是只有在有数据的情况下才需要的功能。 MySQL也进行了分区。 – johannes 2011-04-25 17:08:12

+0

如果这样的查询时间太长,并且他已经在* published *字段上有一个索引,那么很可能该表中有足够的数据。我确实提供了一个链接到MySQL分区文档:) – 2011-04-25 17:10:39

1

需要检查的显而易见的事情是,发布日期是否有索引,并且正在使用?

3

请确保已发布索引,并确保它正在使用中。

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

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

ALTER TABLE tbl_post ADD INDEX (published) 
+0

我设置我的fecha_publicado(或发布)也是索引键,但性能还没有真正提高?我用EXPLAIN进行了检查,它说这个属性是一个索引键。奇怪... – luigi7up 2011-04-26 14:47:49

+0

你可以发布EXPLAIN输出吗? – johannes 2011-04-26 16:41:39

0

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

您还可以更快地做到这一点,因为可能会有3个单独的查询。查询开始数据,查询结束日期,然后将这些值用作目标查询的输入。