Mysql 提高mariaDB查询的sql代码性能
我在DelphiXE8中开发了一个连接到mariaDB的应用程序(版本15.1发行版10.1.31-mariaDB,用于Win32)。 我想提高查询性能。 描述简化的场景: de_用户表(innoDB)(第81762行) Deu doc表(innoDB)(第260452行) 我的问题Mysql 提高mariaDB查询的sql代码性能,mysql,mariadb,groupwise-maximum,Mysql,Mariadb,Groupwise Maximum,我在DelphiXE8中开发了一个连接到mariaDB的应用程序(版本15.1发行版10.1.31-mariaDB,用于Win32)。 我想提高查询性能。 描述简化的场景: de_用户表(innoDB)(第81762行) Deu doc表(innoDB)(第260452行) 我的问题 select User.*, Doc.LastDoc FROM de_Users AS Us LEFT JOIN ( SELECT UserID,MAX(DataFi) AS LastDoc FROM de_do
select User.*, Doc.LastDoc
FROM de_Users AS Us
LEFT JOIN (
SELECT UserID,MAX(DataFi) AS LastDoc
FROM de_doc
GROUP BY UserID
) as Doc on Doc.UserID = Us.ID_U
ORDER BY Us.Name ASC, Doc.LastDoc DESC;
--
解释选择
+------+-------------+----------------+-------+---------------+---------------+---------+----------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+----------------+-------+---------------+---------------+---------+----------------+--------+---------------------------------+
| 1 | PRIMARY | de_User | ALL | NULL | NULL | NULL | NULL | 81762 | Using temporary; Using filesort |
| 1 | PRIMARY | <derived2> | ref | key0 | key0 | 5 | Base.Us.ID_U | 10 | |
| 2 | DERIVED | de_Doc | index | NULL | UserID_LK| 4 | NULL | 260452 | |
+------+-------------+----------------+-------+---------------+---------------+---------+----------------+--------+---------------------------------+
测试phpmyadmin:
83705 total, the query employed 1,0000 sec.
if I remove "order by Doc.LastDoc DESC" it is very fast
83705 total, the query employed 0,0000 sec.
使用delphiEX8开发的应用程序中的测试
view table all rows 2,8 sec.
if I remove "order by Doc.LastDoc DESC" it is very fast
view table all rows 1,8 sec.
如何提高性能?尝试此查询并检查输出是否与您的查询相同
select Us.*, max(Doc.DataFi) as LastDoc
FROM de_Users AS Us
LEFT JOIN de_doc as Doc on Doc.UserID = Us.ID_U
group by Us.ID_U
ORDER BY Us.Name ASC, LastDoc DESC;
尝试此查询并检查输出是否与您的查询相同
select Us.*, max(Doc.DataFi) as LastDoc
FROM de_Users AS Us
LEFT JOIN de_doc as Doc on Doc.UserID = Us.ID_U
group by Us.ID_U
ORDER BY Us.Name ASC, LastDoc DESC;
- 这是不明确的:
索引IDD、用户ID、数据FI
- 大概
应该是User.*
?请注意,“简化”查询可能会将其转化为另一个问题Us.*
- 可能
是不必要的;使用左连接
JOIN
- 您需要这个复合
索引(UserID,LastDoc)
- 您真的希望输出中有82K行吗?客户将如何处理这么多的数据?我这样问是因为如果客户机能够进一步消化结果,那么在SQL中这样做可能会更好
- 计时时,请确保使用SELECT SQL\u NO\u缓存避免查询缓存
- phpmyadmin可能附加了一个限制,从而改变了优化器的功能李>
按t1.a、t2.b排序(不同的表)使得无法使用索引进行排序。这将防止任何类型的查询短路
- 这是不明确的:
索引IDD、用户ID、数据FI
- 大概
应该是User.*
?请注意,“简化”查询可能会将其转化为另一个问题Us.*
- 可能
是不必要的;使用左连接
JOIN
- 您需要这个复合
索引(UserID,LastDoc)
- 您真的希望输出中有82K行吗?客户将如何处理这么多的数据?我这样问是因为如果客户机能够进一步消化结果,那么在SQL中这样做可能会更好
- 计时时,请确保使用SELECT SQL\u NO\u缓存避免查询缓存
- phpmyadmin可能附加了一个限制,从而改变了优化器的功能李>
按t1.a、t2.b排序(不同的表)使得无法使用索引进行排序。这将防止任何类型的查询短路
innodb_buffer_pool_size = 2048M
# Set .._log_file_size to 25 % of buffer pool size
以前
innodb_log_file_size = 64M
(总计83705 del,查询耗时10000秒。)
之后
(83705 del total,查询时间为00000秒。)在my.ini、phpmyadmin中更改这些值就是改进的结果 在我的Delphi应用程序中填充网格所需的时间,现在是1.9秒,而之前是2.8秒 我的电脑有8Gb内存 我可以减少在Delphi中填充网格的时间吗?也许我得提出一个新的要求
innodb_buffer_pool_size = 2048M
# Set .._log_file_size to 25 % of buffer pool size
以前
innodb_log_file_size = 64M
(总计83705 del,查询耗时10000秒。)
之后
(总计83705 del,查询耗时00000秒。)对my.ini[mysqld]部分的建议
sort_buffer_size=2M # from 4096M (4G) of RAM per connection, next 2 are per connect also
read_buffer_size=256K # from 256M to reduce volume of data retrieved by 99%
read_rnd_buffer_size=256K # from ? to a reasonable size
这三个变量可以用set全局变量_name=value动态设置(作为root),请用*1024替换K,用*1024*1024替换M,表示KB和MB。请在正常运行一整天后发布积极/消极结果 对my.ini[mysqld]部分的建议
sort_buffer_size=2M # from 4096M (4G) of RAM per connection, next 2 are per connect also
read_buffer_size=256K # from 256M to reduce volume of data retrieved by 99%
read_rnd_buffer_size=256K # from ? to a reasonable size
这三个变量可以用set全局变量_name=value动态设置(作为root),请用*1024替换K,用*1024*1024替换M,表示KB和MB。请在正常运行一整天后发布积极/消极结果 如果你的目标是“grouwise max”,那么你遗漏了一条条款:
select User.*, Doc.LastDoc
FROM de_Users AS Us
LEFT JOIN
(
SELECT UserID,MAX(DataFi) AS LastDoc
FROM de_doc
GROUP BY UserID
) as Doc ON Doc.UserID = Us.ID_U
AND Doc.LastDoc = Us.DataFi -- this was missing
ORDER BY Us.Name ASC, Doc.LastDoc DESC;
这还将导致交付的行数减少,从而解决性能问题。如果您的目标是“grouwise max”,则您省略了一个条款:
select User.*, Doc.LastDoc
FROM de_Users AS Us
LEFT JOIN
(
SELECT UserID,MAX(DataFi) AS LastDoc
FROM de_doc
GROUP BY UserID
) as Doc ON Doc.UserID = Us.ID_U
AND Doc.LastDoc = Us.DataFi -- this was missing
ORDER BY Us.Name ASC, Doc.LastDoc DESC;
这也会减少交付的行数,从而解决性能问题。表
de_documents
中是否有索引作为index UserID
如果没有,则添加并共享explain
输出,我不理解。我写的代码要复杂得多。我描述了我在两个表和关系上创建了索引。我写了解释结果和我的.ini配置。我写了要优化的查询。是的,我可以阅读你的问题。那么你想说什么呢?对不起,我想提高查询性能。我相信它可以更快。这就是为什么我问列userID
是否有索引?表deu documents
中是否有索引作为index userID
,如果没有添加并共享explain
输出,我不明白。我写的代码要复杂得多。我描述了我在两个表和关系上创建了索引。我写了解释结果和我的.ini配置。我写了要优化的查询。是的,我可以阅读你的问题。那么你想说什么呢?对不起,我想提高查询性能。我相信它可以更快。这就是为什么我问是否有列userID
的索引?它需要相同的时间。没有改进。输出是否正确?如果是这样,则通过删除联接中不需要的子查询来优化上述查询。现在,explain
命令显示了什么?使用选择我们。*。。。。在SQL标准1992中编写的SQL通常是错误的。。但是它可以在SQL标准1999+中有效,在SQL标准1999+中,MySQL 5.7.5+支持函数依赖性。。。但不要在低成本下使用“功能依赖性”