mysql vs sqlserver vs postgres他们以不同方式存储索引吗?

时间:2017-09-22 12:08:02

标签: mysql sql-server postgresql

我目前正在针对特殊用例对三个数据库进行基准测试。

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):

enter image description here

正如您所看到的,当返回部分现有索引(facebook和youtube都被索引)的数据时,mysql非常快。然而,当使用更复杂的查询时,db时序排序反转,该查询按照未直接索引的内容(例如,两列的总和)进行排序。我想我记得有些DB将数据直接存储在索引中,而其他DB则使用指向实际数据的指针。可能是这种情况

2 个答案:

答案 0 :(得分:0)

每个dbms都有一个不同的查询优化器。查询优化器决定何时以及如何最好地使用索引。

在这三个中 - MySQL,SQL Server和PostgreSQL - MySQL拥有最不复杂的查询优化器。如果您的选择基于不代表真实世界查询的查询,您可能对结果不满意。例如,请参阅MySQL的Order By optimization

查询性能不仅仅是dbms是否可以从索引读取值而不从表本身获取的问题。这也是dbms支持哪种索引,如何在磁盘上部署数据库以及如何调整dbms服务器等问题。例如,请参阅PostgreSQL的IndexesTablespaces

答案 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分钟进行一次查询并缓存结果,这样您就可以快速获得结果而不使用快速插入的索引太多了......