(这与here几乎是同一个问题,但我正在寻求对性能的具体澄清,而不是解决任何错误)。
考虑一个数据库表,其中包含一个中等到大量的属性(列),其中大多数是静态的或很少更新的。该表用于读取操作,非常频繁地使用。
如果两个或三个属性(列)经常更新,出于性能原因,是否建议将这些属性(列)拆分成一个单独的表?
我理解这将是一个好处的原因之一是,表的查询缓存在更新时会被擦除。在我的例子中,数据库是MySQL,表类型是InnoDB (行级锁定)。
编辑:频繁更新的列之一不是频繁读取的一部分,但在读取后立即更新。
另一个经常更新的列既是某些频繁读取的一部分,也是随着每次读取而更新的,尽管我可能会对更新进行批量处理。
发布于 2015-07-10 16:37:55
如果您有一个宽表和/或一组相对狭窄的字段,这些字段的访问频率要比其他字段高得多,那么将这些字段与其他字段分开是有意义的。但是,与其将它们规范化为自己的表,不如考虑在现有表中创建一个子表。也就是说,创建一个覆盖索引。
select a, b, c
from table
where c, d, e;在这个简单的例子中,您可以在a,b,c,d,e上创建一个索引。最新情况也是如此:
update table
set d = 'something'
where a, b, e;只要只调用索引中定义的字段,就只需要使用索引。
但永远不要假设任何事。开发定时测试,这样您就可以在前后进行有意义的比较。开发回归测试,这样您就可以看到它是否确实加快了您想要的操作,而不是通过不适当地减缓其他重要操作来实现的。
这是另一个需要考虑的问题。接受上面的查询。假设必须检查数千或数百万行(where子句)才能找到非常少的结果。那么,是否最好创建两个覆盖索引--一个用于选择列表,一个用于where子句?如果它更好(更快),那么应该在选择索引和where索引中定义字段c还是仅在where索引中定义?
我不知道这些问题的答案。你得测试一下。
UPDATE: --如果我理解这个注释,您会对某些字段进行大量查询,而对其他字段进行更新,并且不希望它们相互干扰,因为它们使用不同的字段集。您可以将查询与更新“隔离”。只需在“无锁定”条件下查询即可。
在MySQL中,这个过程是(注意:)--这只适用于InnoDB。参考其他引擎的文档):
set session transaction isolation level read uncommitted;
query1...
query2...
query3...
set session transaction isolation level repeatable read;或者简单的
set transaction isolation level read uncommitted;
query1...
query2...
query3...
commit;您可能仍然需要查看查询和/或更新的索引,但现在这是另一个问题。
https://stackoverflow.com/questions/31326328
复制相似问题