首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL --为什么phpMyAdmin在php/mysqli中的查询速度非常慢?

MySQL --为什么phpMyAdmin在php/mysqli中的查询速度非常慢?
EN

Stack Overflow用户
提问于 2020-05-23 13:28:28
回答 4查看 2.8K关注 0票数 2

编辑__:参见我的答案,主要的区别是phpmyadmin添加的LIMIT,但我仍然不明白,phpmyadmin仍然比mysqli慢。

在我们的数据库(+web)服务器上,在phpmyadmin中执行查询与在php (mysqli)或直接在mariadb服务器上执行查询时性能上有很大差异。60秒vs < 0.01秒!

这个查询功能非常好:

代码语言:javascript
运行
复制
SELECT * FROM `TitelDaggegevens` 
WHERE `datum` > '2020-03-31' AND datum < '2020-05-02' AND `fondskosten` IS NULL 
ORDER BY isbn;

但是,只有在phpMyAdmin中,当我们将2020-05-02更改为2020-05-01时,查询变得非常缓慢。

SHOW PROCESSLIST显示,在运行时,queryu主要是Sending data

数数之后,我执行了以下查询系列:

代码语言:javascript
运行
复制
FLUSH STATUS;
SELECT-query above with one of the two dates;
SHOW SESSION STATUS LIKE 'Handler%';

不同之处令人着迷。(在所有情况下,我省略了等于0的所有值)。随着时间的推移也是一致的。

代码语言:javascript
运行
复制
|                        how:   |     server/MySqli       |      phpMyAdmin 
|         date used in query:   | 2020-05-02 | 2020-05-01 | 2020-05-02 | 2020-05-01
|           records returned:   | 6912       | 1          | 6912       | 1
|                  avg speed:   | 0.27s      | 0.00s      | 0.52s      | 60s (!)
| Variable_name                 | Value      | Value      | Value      | Value
| Handler_icp_attempts          | 213197     | 206286     | 213197     | 0
| Handler_icp_match             | 6912       | 1          | 6912       | 0
| Handler_read_next             | 6912       | 1          | 26651      | 11728896 (!)
| Handler_read_key              | 1          | 1          | 151        | 4
| Handler_commit                | 1          | 1          | 152        | 5
| Handler_read_first            | 0          | 0          | 1          | 1
| Handler_read_rnd_next         | 0          | 0          | 82         | 83
| Handler_read_rnd              | 0          | 0          | 0          | 1
| Handler_tmp_write             | 0          | 0          | 67         | 67

在所有情况下,解释结果都是相同的 (phpmyadmin/mysqli/putty+mariadb)。

代码语言:javascript
运行
复制
    [select_type] => SIMPLE
    [table] => TitelDaggegevens
    [type] => range
    [possible_keys] => fondskosten,Datum+isbn+fondskosten
    [key] => Datum+isbn+fondskosten
    [key_len] => 3
    [ref] => 
    [Extra] => Using index condition; Using filesort

唯一的区别是行:

代码语言:javascript
运行
复制
    [rows] => 422796 for 2020-05-01
    [rows] => 450432 for 2020-05-02

问题

你能告诉我们的方向吗?,我们可以在哪里找到解决这个问题的方法?为了优化mariadb服务器(除了phpmyadmin之外,现在是最优的),我们已经工作了一周,并将一些问题缩小到下面的示例。我们经常使用phpmyadmin,但是对于表面下的内容几乎没有经验(比如它如何连接到db)。

关于索引/排序的

在慢速查询中,如果我们将ORDER BY从索引的isbn字段更改为非索引字段,或者完全忽略ORDER BY,那么一切都有正常的闪电速度。将ORDER BY更改为主键id也会降低速度,但速度仍然是索引isbn字段的10倍。

我们*知道*我们可以通过更好的索引来解决这个特定的查询,我们已经准备好实现这个索引了。但是,我们想知道phpmyadmin对mysqli/直接造成不同时间的原因。

详细信息:

TitelDaggegevens包含<1100万条记录,甚至不包含3Gb,并且已被OPTIMIZEd (重建)

表格结构:

代码语言:javascript
运行
复制
CREATE TABLE `TitelDaggegevens` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `isbn` decimal(13,0) NOT NULL,
 `datum` date NOT NULL,
 `volgendeDatum` date DEFAULT NULL,
 `prijs` decimal(8,2) DEFAULT NULL,
 `prijsExclLaag` decimal(8,2) DEFAULT NULL,
 `prijsExclHoog` decimal(8,2) DEFAULT NULL,
 `stadiumDienstverlening` char(2) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
 `stadiumLevenscyclus` char(1) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
 `gewicht` double(7,3) DEFAULT NULL,
 `volume` double(7,3) DEFAULT NULL,
 `24uurs` tinyint(1) DEFAULT NULL,
 `UitgeverCode` varchar(4) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
 `imprintId` int(11) DEFAULT NULL,
 `distributievormId` tinyint(4) DEFAULT NULL,
 `boeksoort` char(1) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
 `publishingStatus` tinyint(4) DEFAULT NULL,
 `productAvailability` tinyint(4) DEFAULT NULL,
 `voorraadAlles` mediumint(8) unsigned DEFAULT NULL,
 `voorraadBeschikbaar` mediumint(8) unsigned DEFAULT NULL,
 `voorraadGeblokkeerdEigenaar` smallint(5) unsigned DEFAULT NULL,
 `voorraadGeblokkeerdCB` smallint(5) unsigned DEFAULT NULL,
 `voorraadGereserveerd` smallint(5) unsigned DEFAULT NULL,
 `fondskosten` enum('depot leverbaar','depot onleverbaar','POD','BOV','eBoek','geen') COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `ISBN+datum` (`isbn`,`datum`) USING BTREE,
 KEY `UitgeverCode` (`UitgeverCode`),
 KEY `Imprint` (`imprintId`),
 KEY `VolgendeDatum` (`volgendeDatum`),
 KEY `Index op voorraad om maxima snel te vinden` (`isbn`,`voorraadAlles`) USING BTREE,
 KEY `fondskosten` (`fondskosten`),
 KEY `Datum+isbn+fondskosten` (`datum`,`isbn`,`fondskosten`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=16519430 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci 

虚拟web+database+mail服务器的配置:

代码语言:javascript
运行
复制
MariaDB 10.4 
InnoDB
CentOs7 
phpMyAdmin 4.9.5
php 5.6
Apache 

一些重要的mariadb配置参数与虚拟we服务器默认的配置参数不同:

代码语言:javascript
运行
复制
[mysqld]
innodb_buffer_pool_size=2G
innodb_buffer_pool_instances=4
innodb_flush_log_at_trx_commit=2

tmp_table_size=64M
max_heap_table_size=64M

join_buffer_size=4M
sort_buffer_size=8M

optimizer_search_depth=5
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-05-27 10:44:04

我们已经有专家看过了,除了你所有的提示。

经过多次测试,phpMyAdmin添加的phpMyAdmin是导致这种极端延迟的唯一原因。专家没有发现mysqli/phpmyadmin和直接在mariadb服务器上执行它之间的区别。

有时,查询中的非常小的差异(比如为只返回一条记录的查询添加一个限制)可能会导致查询花费100.000倍的时间,因为它将扫描整个索引,因为引擎将看到另一个适合该查询的策略。这是标准的行为。

我们已经找到了一个消除了这个具体问题的索引,现在我们也确信我们的DB没有什么问题。一些我们不确定的事情,因为这似乎是极端的行为。所以:无事生非。

然而,我从这次经历中学到了很多。都来自我们的专家和这个社区。我了解了MySQL诊断、日志记录、mariaDB如何处理查询.对于每一个被证明不是问题的诊断,我学会了在表、索引或查询中避免或争取的东西。

谢谢大家,尤其是里克·詹姆斯、威尔逊·哈克和“利用命运”

票数 0
EN

Stack Overflow用户

发布于 2020-05-23 13:59:26

最大的区别是当然是phpmyadmin为查询添加了一个限制的。这给出了主要解释。我不敢相信这不是我们第一次尝试,我很尴尬。

然而,phpMyAdmin和mysqli之间的速度差异仍然很大,而且结果仍然不同(服务器或mysqli上的2020-05-01):

代码语言:javascript
运行
复制
+----------------------------+----------+
| Variable_name              | Value    |
+----------------------------+----------+
| Handler_commit             | 1        |
| Handler_read_first         | 1        |
| Handler_read_next          | 11733306 |
| rest                       | 0        |
+----------------------------+----------+

使用limit和2020-05-02的速度:使用limit和2020-05-01的速度都在0.17-0.2之间: php/mysqli:声称:3.5秒,但是页面加载了大约30秒putty/mariadb: claimes也是3.5秒,但是显示了大约30秒的phpmyadmin: claimed和实时的大约60秒的结果。

此外,解释也有很大的变化,但有一定的限制:

( datum<20200501为1268行,datum<20200502为1351行)

代码语言:javascript
运行
复制
+------+-------------+------------------+-------+------------------------------------+------------+---------+------+------+-------------+
| id   | select_type | table            | type  | possible_keys                      | key        | key_len | ref  | rows | Extra       |
+------+-------------+------------------+-------+------------------------------------+------------+---------+------+------+-------------+
|    1 | SIMPLE      | TitelDaggegevens | index | fondskosten,Datum+isbn+fondskosten | ISBN+datum | 9       | NULL | 1351 | Using where |
+------+-------------+------------------+-------+------------------------------------+------------+---------+------+------+-------------+
票数 1
EN

Stack Overflow用户

发布于 2020-05-24 12:56:32

考虑制作optimizer_search_depth=16而不是5,并从TitelDaggegevens中选择*,其中datum在“2020-03-31”和“2020-05-02”之间和fondskosten之间的顺序为空;

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61972759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档