我正在使用带有innodb的mysql在Rails中开发应用程序。我需要经常获取完整的表计数,并且我理解使用innodb,计算表中的所有记录可能非常昂贵,因为它需要全表扫描。我正在查看rails控制台中的典型表,并查看计数记录的查询时间。到目前为止我发现的是第一次计算记录需要很长时间,但在后续尝试中它会快得多。例如:
2.2.2 :002 > Request.count
(683.7ms) SELECT COUNT(*) FROM `requests`
=> 260588
2.2.2 :003 > Request.count
(47.6ms) SELECT COUNT(*) FROM `requests`
=> 260588
2.2.2 :004 > Request.count
(46.7ms) SELECT COUNT(*) FROM `requests`
=> 260588
所以,首先,我是否需要担心优化此结果?也许计数是由Rails或mySql或InnoDB缓存的,没有什么可担心的。
我将假设在生产环境中仍有一些问题需要担心,其中多个用户在任何给定时间写入表。在这种情况下,我如何“重置”缓存或任何给我一个不切实际的阳光前景的计数时间,以便我可以做一些诚实的基准测试?我试过写一个记录,或只是用reload!
重新加载控制台,但我从来没有得到最初的长时间。我敢打赌,如果我退出控制台并重新启动会执行此操作的mysql,但我宁愿不必那么努力。
最后,我听说像下面这样的查询会运行得更快:
select count(*) from requests use index(<index_name>);
似乎最自然的索引是id
字段。
select count(*) from service_requests use index(id)
但是这给了我以下错误:
ERROR 1176 (42000): Key 'id' doesn't exist in table 'requests'
但是id不仅仅是一把钥匙,它是主键。在某些表上,它是唯一的索引。为什么id不被认为是关键?
答案 0 :(得分:1)
要优化它,请运行optimize table
,然后您可以创建另一个不是主键的索引,因为InnoDB使用群集主键。
创建另一个索引时,您必须在另一个易于扫描的字段上创建它,而不是像文本字段(如果它适用于请求)。
错误 - 如果您继续使用主键而不是创建另一个索引,无论出于何种原因:
正如您所提到的那样,主键确实是id
,然后在use index(id)
上使用id
(查询来自您的表中的PK)无法正常工作,它将是USE INDEX (PRIMARY)
。要查看该表的其他索引,请运行SHOW INDEX FROM <Table>
命令,这将显示该表的其他索引名称。
更多信息: http://dev.mysql.com/doc/refman/5.7/en/optimize-table.html http://dev.mysql.com/doc/refman/5.7/en/index-hints.html
答案 1 :(得分:0)
OPTIMIZE TABLE
;它几乎从未提供任何改进。USE INDEX
或FORCE INDEX
。今天它可能对你有所帮助,但明天可能会让事情变得更糟。 Optimize动态选择“最佳”索引,并且在选择时通常是“正确的”。PRIMARY KEY
可能是用于完整表COUNT(*)
的最差索引。SELECT COUNT(*)
需要时间(对于InnoDB),因为它必须扫描整个表,绕过正在进行的任何事务。INDEX(foo)
可能会有所帮助,其中foo
是一个小列。但是,这不太可能超过速度的两倍。innodb_buffer_pool_size
配置为可用 RAM的70%左右,以便减少I / O. results
中有这么多行需要“太长”,那么这个数字可能毫无意义。请注意一些搜索引擎如何不再说“1,234,566个结果中的10个”,甚至“大约1,000,000个结果中的10个”。那是因为他们发现不值得计算甚至估算。SELECT
有WHERE
条款,那么我的大部分答案都不适用。