从理论上讲,这个SQL查询是否太大而无法在加载下快速服务?

时间:2011-03-16 19:40:42

标签: mysql sql-server database oracle postgresql

我有一个sql查询,可以轻松返回关系数据库表的70,000行(涉及一些连接)。此结果集的总大小约为20mb。表的总大小约为1000万行。

我在这里缺乏视角,所以我想知道这个大小的查询是否实际上能够快速提供,即使在网页上每秒几百个请求?此外,这不是一个只读表:有相当多的更新/删除(介于3:1和10:1之间的读/写比率取决于一年中的时间)

我知道我需要索引等等。我想知道的是,如果单个数据库服务器(比如4gb ram和现代四核CPU)甚至可以在理论上服务于此而不会破坏cpu或磁盘IO的地狱并且表现糟糕?

4 个答案:

答案 0 :(得分:7)

你没有提供很多关于你的查询实际情况的背景信息,但是我将以PostgreSQL为例,向您介绍如何估计您的期望是否切合实际。 / p>

准备一个10M行的虚表,每行80字节的填充数据:

create table foo as select
    generate_series(1,10000000) as foo_id,
    repeat('a', 80) as filler;
create unique index foo_foo_id on foo (foo_id);
vacuum analyze foo;

此表总计1400 MB,包括索引,因此它完全适合我的操作系统缓存,但不适合PostgreSQL的共享缓冲区。

创建自定义pgbench脚本以获取由索引排序的70000行:

\setrandom key 1 9000000
SELECT * FROM foo WHERE foo_id > :key ORDER BY foo_id LIMIT 70000;

以下是在我的4核台式电脑(AMD Phenom II X4 955)上运行基准测试1分钟的结果:

% pgbench -j 4 -c 4 -T 60 -n -f script.pgb
transaction type: Custom query
scaling factor: 1
query mode: simple
number of clients: 4
number of threads: 4
duration: 60 s
number of transactions actually processed: 3922
tps = 65.309954 (including connections establishing)
tps = 65.316916 (excluding connections establishing)

请注意,客户端(pgbench)和服务器位于同一台物理计算机上。实际上它们会有所不同,因此网络开销和吞吐量等都会发挥作用。

这种天真的配置每秒可以处理大约65个这样的查询。远低于“每秒几百个请求”,因此您需要很多更强大的服务器来处理这种工作负载。可以选择使用多个从站进行复制。

为了获得更真实的结果,您应该调整pgbench脚本并测试数据,使其与您的工作负载更接近。

答案 1 :(得分:4)

嗯,不。但是,如果您可以限制结果集(显示分页),缓存结果,并可能预处理/转换数据(实际上,创建自己的优化索引),可以。< / p>

编辑:我对预处理的意思是定期运行一个cronjob,将您的数据按摩成一种可以很容易被消费者查询的形式,例如:临时或中间表(不涉及联接)。这样,您只需每隔几秒钟或几分钟执行一次加密查询。如果您依赖于准确的实时查询,则可能无法进行cronjob优化。

为了能够在不重载数据库层的情况下回答所有查询,您可以将先前搜索的可重用结果缓存在内存缓存中,例如,分布式缓存)。

答案 2 :(得分:2)

这在很大程度上取决于索引的选择性,以及您对数据的处理方式。如果你将结果集输送到文件进行自动处理,我会说70K行和20mb不是show-stopper。但如果您尝试将其加载到网页中,它可能会成为一个阻碍。

无论如何,我鼓励你考虑一下网页上有人需要看到70,000行和20兆字节的真正原因。他们一次试图用那么多数据来完成什么?

答案 3 :(得分:2)

使用您描述的硬件,您遗漏了最重要的部分:存储。典型的数据库受到磁盘和内存的瓶颈。现代CPU的速度如此之快,通常不是问题所在。如果你得到严重的突袭或SSD,你可以做一些严肃的事情。对于您描述的大多数工具,10M行表将始终存在于内存中。

然而,您描述的问题可能会在锁定时挂起。有许多用户在表中读取和写入小事实,然后您阅读该表的大部分内容。这是不同的方式,称为isolation levels。使用您描述的负载,您可能希望完全避免这种情况。

这是一项名为datawarehousing的运动中的经典问题,您希望针对在线系统运行大型分析查询。例如,您希望使用日志传送创建该表的第二个副本。您标记的大多数数据库都可以执行此操作。日志传送将在快速更改的表和分析表之间创建缓冲区。当你锁定这个分析表时,更新就会结束,直到你完成为止。还有一些人从这张桌子上读书,所以你自己拥有一切。从本质上讲,这将只占您数据库最大吞吐量的百分之几。如果你已经接近那个已经存在扩展问题。如果您确实需要查看最新数据,请查看实时BI。

同样拥有该数据的第二个副本可以让您以一种非常容易查询的方式对其进行不同的结构化。中心的想法是Star Schema。

关心GJ