Mysql 提高大型表SQL查询速度的方法
我有一个1000万行、3列的MySQL表,格式如下:Mysql 提高大型表SQL查询速度的方法,mysql,sql,datetime,query-optimization,where-clause,Mysql,Sql,Datetime,Query Optimization,Where Clause,我有一个1000万行、3列的MySQL表,格式如下: id time num ca65e871-d758-437e-b76f-175234760e7b 2020-11-14T23:08:05.553770Z 11112222222 ... 我试图在所需的时间范围内计算特定数量的事件,如下所示: "SELECT COUNT(*) FRO
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环境(Python3.x)的查询,该环境使用pymysql
包连接到MySQL数据库。在10毫米行上,此执行持续约2.8秒。在time
和num
列上添加索引后,执行速度几乎是原来的两倍:1.5秒
我的问题是我能进一步加快速度吗
理想情况下,执行时间应该在200毫秒以下,所以我不知道这是否可行。提前谢谢你 对于此查询:
SELECT COUNT(*)
FROM TABLE_NAME
WHERE time > '2020-11-14T23:08:05.553752Z' AND num = '11112222222'
您需要在(num,time)
上建立多列索引。索引中列的顺序很重要。首先需要具有相等谓词的列,然后是具有不等谓词的列
我对数据类型有点怀疑。如果num
是数字数据类型(看起来像int
),则应根据文字数字对其进行过滤:
num = 11112222222
进一步加快查询速度的唯一方法是收缩数据类型
num='1111222222'
无需更改,但
BIGINT
为8字节。如果你能承受40亿的上限,那么使用INT UNSIGNED
(4字节)
不幸的是,MySQL不能将字符串'2020-11-14T23:08:05.553770Z'
理解为DATETIME
(也不能理解为TIMESTAMP
),如果time
是VARCHAR(27),则一切正常。但是,如果您可以切换到兼容的格式,则使用DATETIME(6)
可以节省大量空间,而DATETIME(6)仅为8个字节(而varchar为28个字节)
uuid
由于其随机性,体积庞大且效率低下。您可能正在使用字符(36)ascii字符集--36字节。将它(参见MySQL 8.0)打包为`二进制(16)--16字节
这将大大缩小表和索引,从而在性能上提供一些改进
对于UUID的转换代码:MySQL 8.0也有一对类似的内置代码
另外,
T
和Z
不是DATETIME(6)
的有效字符,因此需要进行一些编辑。请更具体地说明您的起点,例如概述不同的层以及它们对查询持续时间的影响。您应该跟踪不同的调用,并检查是查询执行、网络传输还是Python-/pymysql开销。至少切分和并行查询总是有效的,但会增加竞争性。非常感谢。我在(num,time)
上添加了一个索引,现在执行时间不到5毫秒。非常好的建议,再次感谢!顺便说一句,num
属于bigint
类型,更改过滤(如您所说的针对文字数字)没有多大帮助。你认为我应该把num
列改成varchar
?这有助于进一步加快查询速度吗?在这种情况下,'123'
在开始查询之前会变成123
。所以,你不会看到速度上的明显差异。相反的是程序员会被拧死:varchar\u col=123
转换列,而不是123
。也就是说,在你的情况下;将num
保留为BIGINT
,不要担心文字。谢谢!我将使用数据包binary
形式的datetime(6)
和UUID
。关于后者,我认为这是一种很好的方法@马卡罗尼-我添加了两段。