我目前正在针对特殊用例对三个数据库进行基准测试。
tabledata(10,000,000行)
id, facebook[random int 0-1,000,000], youtube[random int 0-1,000,000]
1, 322342, 293492
2, ...
6个查询:
SELECT youtube, facebook FROM file_results WHERE youtube > 500000 AND facebook > 500000 ORDER BY youtube DESC LIMIT 100
SELECT youtube, facebook, youtube+facebook as total FROM file_results WHERE facebook+youtube > 1000000 ORDER BY youtube DESC LIMIT 100
SELECT youtube, facebook, youtube+facebook as total FROM file_results WHERE facebook > 500000 AND youtube > 500000 ORDER BY facebook+youtube DESC LIMIT 100
SELECT youtube, facebook, youtube+facebook as total FROM file_results WHERE facebook > 900000 AND youtube > 900000 ORDER BY facebook+youtube DESC LIMIT 100
SELECT youtube, facebook, youtube+facebook as total FROM file_results WHERE facebook+youtube > 1000000 ORDER BY facebook+youtube DESC LIMIT 100
SELECT youtube, facebook, youtube+facebook as total FROM file_results WHERE facebook+youtube > 1800000 ORDER BY facebook+youtube DESC LIMIT 100
6结果(ms):
正如您所看到的,当返回部分现有索引(facebook和youtube都被索引)的数据时,mysql非常快。然而,当使用更复杂的查询时,db时序排序反转,该查询按照未直接索引的内容(例如,两列的总和)进行排序。我想我记得有些DB将数据直接存储在索引中,而其他DB则使用指向实际数据的指针。可能是这种情况
答案 0 :(得分:0)
每个dbms都有一个不同的查询优化器。查询优化器决定何时以及如何最好地使用索引。
在这三个中 - MySQL,SQL Server和PostgreSQL - MySQL拥有最不复杂的查询优化器。如果您的选择基于不代表真实世界查询的查询,您可能对结果不满意。例如,请参阅MySQL的Order By optimization。
查询性能不仅仅是dbms是否可以从索引读取值而不从表本身获取的问题。这也是dbms支持哪种索引,如何在磁盘上部署数据库以及如何调整dbms服务器等问题。例如,请参阅PostgreSQL的Indexes和Tablespaces。
答案 1 :(得分:0)
对于最后的查询,只需在(facebook + youtube)上创建一个表达式/函数索引,这将大大加快速度。 Postgresql可以很容易地做到这一点,只需使用:
CREATE INDEX foo_idx ON table(facebook+youtube)
我解决MySQL也可以做到这一点,搜索"虚拟列和有效功能索引"在文档中,至于SQL Server,我不知道,但考虑到它的声誉,我希望它能做到......
你也可以使用覆盖索引,如:
(youtube,facebook)
(facebook,youtube)
以及包括facebook + youtube总和在内的各种变体,但最终会有大量索引减慢插入速度并使用大量空间,因此这是一种妥协。
但是,我想你的前100名"查询不会每2秒更改一次,因此即使它们有点慢,您也可以使用cron每5分钟进行一次查询并缓存结果,这样您就可以快速获得结果而不使用快速插入的索引太多了......