2010-07-14 158 views
0

我有大约100万行,所以它非常缓慢。以下是查询:有没有办法加快这个查询没有WHERE子句?

$sql = "SELECT `plays`,`year`,`month` FROM `game`"; 

我抬头索引,但它只有当我有一个'where'子句时有意义。

任何想法?

+3

你需要全部100万吗?你能选择第一个1,10,1000吗? – hookedonwinter 2010-07-14 22:41:58

+0

全部100万。 看着这些答案,我可能需要缓存结果。 – Citizen 2010-07-14 22:53:50

+0

一百万行是通过电线返回的 - 不要假定所花的时间完全在于MySQL。 – 2010-07-15 01:32:08

回答

3

即使没有WHERE子句,索引也可以有所不同,具体取决于表中的其他列。如果您选择的3列仅占表格内容的一小部分,则其覆盖索引可减少需要扫描的页面数量。

虽然不移动尽可能多的数据,但通过添加WHERE子句或在数据库中执行处理可能会更好。

+0

+1:索引使用不仅限于WHERE子句 - 如果优化器看起来合适,JOIN,SELECT和ORDER BY可以触发使用。麻烦的是,MySQL只为您在EXPLAIN计划中看到的每条语句使用一个索引。 – 2010-07-15 01:30:47

1

不能从内存高速缓存而不是从数据库获取数据,因此无法更快地进行该查询。获取一百万行需要时间。如果您需要更多速度,请确定您是否可以让数据库执行一些工作,例如总和/组合的东西。

如果您没有使用所有行,则应该使用SQL中的LIMIT子句来提取仅一百万行的特定范围。

2

如果你并不需要所有的100万条记录,你可以拉n记录:

$sql = "SELECT `plays`,`year`,`month` FROM `game` LIMIT 0, 1000"; 

其中第一个数字是偏移量(从哪里开始),第二个数字是行数。如果只拉取选定数量的记录,您可能也想使用ORDER BY

1

如果您确实需要所有100万行来构建输出,那么从数据库方面可以做的事情就不多了。

但是,您可能想要将结果缓存在应用程序端,以便下次您希望提供相同的输出时,可以从缓存中返回已处理的输出。

1

现实的答案是否定的。对查询没有任何限制(例如WHERE子句或LIMIT),那么您几乎可以保证每次都进行全表扫描。

减少扫描时间的唯一方法是减少数据(或者可能是更快的磁盘)。有可能您可以重新处理数据以提高行数(在某些情况下使用CHARS而不使用VARCHARS,而使用TINYINTS而不使用INTS等),但您真的不会看到太多的速度差异一种微观优化。索引是它的位置。

一般情况下,如果你遇到这样的情况,你不能使用索引,但你有大表,那么这是业务逻辑,需要一些重新工作。你是否总是需要选择每一条记录?你可以做一些应用程序端缓存吗?你可以将数据分成更小的集合或表格,也许按日或月组织?等等