简体   繁体   English

mysql:如何提高这个mysql select语句的性能

[英]mysql: how can I improve performance for this mysql select statement

I have created an sql table where I have indexed files on disk. 我已经创建了一个sql表,我在磁盘上有索引文件。 There are over 1 million records on the table. 桌上有超过100万条记录。 I have added indexes for ext and size, but it still takes over a minute to execute this query which tells me the amount of space used by ext. 我已经为ext和size添加了索引,但执行此查询仍然需要一分钟,这告诉我ext使用的空间量。 How can I improve performance on this select? 如何提高此选择的性能?

select ext,
     ROUND((sum(size) / (1073741824))) as TotalSizeGB,
     count(*) as Count
  from fileindex
group by ext
order by TotalSizeGB desc;

Explain output: 解释输出:

|| *id* || *select_type* || *table*   || *type* || *possible_keys* || *key* || *key_len* || *ref*  || *rows*  || *Extra*                                      ||
|| 1    || SIMPLE        || fileindex || index  || _NULL_          || ext   || 27        || _NULL_ || 1892234 || Using index; Using temporary; Using filesort ||

Use MySQL Triggers so as rows are INSERT'ed into fileindex , it does something like UPDATE meta SET value=value+NEW.size WHERE name='fileindex.count'; 使用MySQL触发器,以便将行插入到fileindex ,它执行类似UPDATE meta SET value=value+NEW.size WHERE name='fileindex.count'; .

delimiter |

DROP TRIGGER fileindexafterinsert;|
CREATE TRIGGER fileindexafterinsert AFTER INSERT ON fileindex
    FOR EACH ROW BEGIN
        update meta set value=value+NEW.size where name=CONCAT('fileindex.',NEW.ext);
    END;
|
DROP TRIGGER fileindexafterdelete;|
CREATE TRIGGER fileindexafterdelete AFTER DELETE ON fileindex
    FOR EACH ROW BEGIN
        update meta set value=value-OLD.size where name=CONCAT('fileindex.',OLD.ext);
    END;
|

Then you simply can do SELECT * FROM meta WHERE name='fileindex.exe' LIMIT 1 which should return in less than 0.01s. 然后你就可以做SELECT * FROM meta WHERE name='fileindex.exe' LIMIT 1 ,它应该在0.01s以内返回。

The query as written is always going to hit every row in the table - so there really is a limit to how quickly it can perform. 写入的查询总是会触及表中的每一行 - 因此它的执行速度确实存在限制。 If you really want this result to be something returned quickly, you might want to add another table to keep the total size of each ext, and update it with triggers whenever an operation takes place on your main table. 如果您确实希望此结果快速返回,则可能需要添加另一个表以保持每个ext的总大小,并在主表上执行操作时使用触发器更新它。

As I can't see any obvious flaw with your MySQL syntax, if you want it faster than that, I would suggest going NoSQL, and using a document database that supports Map-Reduce such as Hadoop or CouchDB . 由于我没有看到你的MySQL语法有任何明显的缺陷,如果你想要比它更快,我建议去NoSQL,并使用支持Map-Reduce的文档数据库,如HadoopCouchDB You could host this on a cluster (read: hundreds) of machines on EC2 (ok, I'm joking, but seriously you can run 1 node per CPU core for max-speed on 1 box). 您可以在EC2上的一个集群(读取数百个)上托管这个(好吧,我在开玩笑,但是认真的是,你可以在每个CPU核心上运行1个节点,以便在1个盒子上实现最大速度)。

Your query is going to hit each record of the table, therefore you don't want to slow things down by first hitting an index and then the table, as obviously this will lead to 2 IOs per record from the table (1 for the index and 1 for the actual table data). 您的查询将命中表的每个记录,因此您不希望通过首先命中索引然后是表来减慢速度,因为显然这会导致表中每个记录有2个IO(索引为1)和1表示实际的表数据)。

Therefore the first question becomes how can you speed a full table scan? 因此,第一个问题是如何加快全表扫描速度?

Tune IO. 调整IO。 Are your disks fast, defragged, not shared (with other data, applications, etc), etc. 您的磁盘是快速,碎片整理,不共享(与其他数据,应用程序等),等等。

ALternately, consider denormalisation; 或者,考虑非规范化; eg a trigger on your table that counts and sums the appropriate data with each insert, update and deletion and stores this value in another table. 例如,您的表上的触发器,用于计算每个插入,更新和删除的相应数据并将其相加,并将此值存储在另一个表中。 Then query for the single row of data in this other table. 然后在另一个表中查询单行数据。

Add a covering index which will basically have all the columns you need in memory. 添加覆盖索引,它基本上具有内存中所需的所有列。 I would recommend: alter table fileindex add index covering (ext,TotalSizeGB, size) 我建议: alter table fileindex add index covering (ext,TotalSizeGB, size)

Should work well. 应该运作良好。 (hopefully) (希望)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM