加快大表SQL查询的方法

Posted

技术标签:

【中文标题】加快大表SQL查询的方法【英文标题】:Ways to speed up SQL query on large table 【发布时间】:2020-11-18 10:51:35 【问题描述】:

我有一个 1000 万行和 3 列的 mysql 表,格式如下:

id                                     time                               num

ca65e871-d758-437e-b76f-175234760e7b  2020-11-14T23:08:05.553770Z         11112222222
...

我正在尝试在所需的时间范围内计算特定数量的出现次数,如下所示:

"SELECT COUNT(*) FROM TABLE_NAME WHERE time >'2020-11-14T23:08:05.553752Z' and num = '11112222222'"

我正在从 Python 环境 (python 3.x) 运行查询,该环境使用 pymysql 包连接到 MySQL 数据库。在 10MM 行上,此执行持续大约 2.8 秒。在timenum 列上添加索引后,执行速度几乎快了两倍:1.5 秒

我的问题是我可以进一步加快速度吗?

理想情况下,执行时间应该低于 200 毫秒,所以我不知道这是否可能。提前谢谢!

【问题讨论】:

请更具体地说明您的起点,例如概述不同的层以及它们如何影响您的查询持续时间。您应该跟踪不同的调用并检查它是查询执行、网络传输还是 Python-/pymysql-overhead。至少分片和并行查询总是有效,但会增加复杂性。 【参考方案1】:

对于这个查询:

SELECT COUNT(*) 
FROM TABLE_NAME 
WHERE time > '2020-11-14T23:08:05.553752Z' AND num = '11112222222'

您希望在(num, time) 上建立一个多列索引。索引中列的顺序很重要。您首先需要具有等式谓词的列,然后是具有不等式谓词的列。

我对数据类型有点怀疑。如果num 是数字数据类型(看起来像int),那么您应该根据文字数字对其进行过滤:

num = 11112222222

【讨论】:

非常感谢。我在(num, time) 上添加了一个索引,现在执行时间不到 5 毫秒。惊人的建议,再次感谢!顺便说一句,numbigint 类型,并且更改过滤(针对您所说的文字数字)并没有太大帮助。你认为也许我应该把num 列转成varchar 吗?这是否有助于进一步加快查询速度? 在这种情况下,'123' 在开始查询之前会变成123。因此,您不会看到明显的速度差异。相反的是程序员被搞砸的地方:varchar_col = 123 转换列,而不是123。也就是说,就您而言;将num 保留为BIGINT,不要担心文字。【参考方案2】:

进一步加快查询速度的唯一方法是缩小数据类型。

num = '11112222222' 不需要更改,但是...

BIGINT 是 8 个字节。如果您可以忍受 40 亿的限制,请使用 INT UNSIGNED(4 个字节)。

不幸的是,MySQL 不将字符串 '2020-11-14T23:08:05.553770Z' 理解为 DATETIME(也不理解 TIMESTAMP)如果 time 是 VARCHAR(27),那么一切正常。但是如果你可以切换到兼容的格式,DATETIME(6) 会节省很多空间,它只有 8 个字节(而 varchar 是 28 个字节)。

UUIDs 体积庞大且效率低下,因为它们具有随机性。您可能正在使用 CHAR(36) CHARACTER SET ascii -- 36 字节。将它(参见 MySQL 8.0)打包成 `BINARY(16) -- 16 字节。

这些会显着缩小表和索引,从而提高性能。

对于 UUID 的转换代码:http://mysql.rjweb.org/doc.php/uuid#code_to_do_it MySQL 8.0 也有一对类似的内置函数。

另外,TZ 不是 DATETIME(6) 的有效字符,因此需要进行一些编辑。

【讨论】:

谢谢!我将使用datetime(6)UUID 在数据包binary 表单中。关于后者,我认为这是一个好方法吗? mysqltutorial.org/mysql-uuid @Makaroni - 我添加了几段。

以上是关于加快大表SQL查询的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何加快创建大表 AlphaNumeric 代码的 SQL 脚本

如果有一种方法可以预先计算 SQL 视图以加快查询速度?

sql优化原则与技巧

如何优化这个大表SQL查询的响应时间?

在 3 个大表上使用内连接优化 SQL 查询

在sql server 2008中查询大表[重复]