我正在尝试解决a到mysql-5.0 db的延迟问题。
SELECT SUM(items) FROM tbl WHERE col = 'val'
col
上有一个索引,在最坏的情况下总和不超过10000个值(count(items)
的所有值的平均值col
大约为10)。< / LI>
我正在寻找的结果是每一个查询&lt; 1秒。有没有办法在不更改表格的情况下改善选择时间?或者,是否有任何有趣的变化有助于解决问题?我想过只需要一张表,在每次插入后立即更新每个col的当前总和 - 但也许有更好的方法可以做到这一点?
答案 0 :(得分:2)
另一种方法是添加摘要表:
create table summary ( col varchar(10) primary key, items int not null );
并向tbl添加一些触发器,以便:
插入时:
insert into summary values( new.col, new.items )
on duplicate key update set summary.items = summary.items + new.items;
关于删除:
update summary set summary.items = summary.items - old.items where summary.col = old.col
更新:
update summary set summary.items = summary.items - old.items where summary.col = old.col;
update summary set summary.items = summary.items + new.items where summary.col = new.col;
这会降低您的插入速度,但允许您在
的摘要表中单击一行select items from summary where col = 'val';
这个问题的最大问题是引导汇总表的值。如果您可以使应用程序脱机,则可以使用tbl中的值轻松初始化摘要。
insert into summary select col, sum(items) from tbl group by col;
但是,如果您需要保持服务运行,则要困难得多。如果您有副本,则可以停止复制,构建摘要表,安装触发器,重新启动复制,然后将服务故障转移到使用副本,然后在已停用的主服务器上重复此过程。
如果你不能这样做,那么你可以一次更新摘要表一个col的值,以减少影响:
lock table write tbl, summary;
delete from summary where col = 'val';
insert into summary select col, sum(items) from tbl where col = 'val';
unlock tables;
或者如果你能忍受长时间的停电:
lock table write tbl, summary;
delete from summary;
insert into summary select col, sum(items) from tbl group by col;
unlock tables;
答案 1 :(得分:1)
覆盖索引应该有所帮助:
create index cix on tbl (col, items);
这样可以在不读取数据文件的情况下执行求和 - 这应该更快。
您还应该跟踪密钥缓冲区的有效性,以及是否需要为其分配更多内存。这可以通过轮询服务器状态并观察'key%'值来完成:
SHOW STATUS LIKE 'Key%';
key_read_requests(即索引查找的数量)与key_reads之间的比率(即需要从磁盘读取索引块的请求数量)非常重要。磁盘读取次数越多,查询运行得越慢。您可以通过增加配置文件中的密钥缓冲区大小来改进这一点。