查询性能调试
Query performance debuging
我最近在 Oxid 6 中安装了一个新模块 (paypal express)。0.x 后端。
安装后,我后台的后台菜单点"orders"超时了。导致查询需要的时间太长。我无法查看订单(这是 CMS 供应商资源)。
我已经尝试通过我们的托管主机支持来调试它,他们将我们的 ram 加倍以增加 mysql 缓冲区大小以及 php 超时等 php.ini.
在主机 php.ini 更改后,即使主机增加了查询缓冲区等,我仍然看到状态为 "Copying to tmp table" 的查询
问题:
我真的不确定是什么问题。有人知道我还可以尝试什么吗?
我无法想象这个小连接需要这么多缓冲区 space 和执行时间。特别是因为连接到 payppaypalpluspayment 与 oxv_oxpayments_de 相同,后者是即时的并且在相同的主键上。
这是我在进程列表
中看到 运行 的查询
显示第 0 - 0 行(总共 1 行,查询耗时 200.9683 秒。)已经从 php.ini 更改后的大约 10 分钟减少
select count(*) from `oxorder`
LEFT JOIN `oxv_oxpayments_de` AS `payments` on `payments`.oxid=oxorder.oxpaymenttype
LEFT JOIN `oxv_oxpayments_de` AS pluspayments ON pluspayments.oxid = oxorder.oxpaymenttype
LEFT JOIN payppaypalpluspayment ON payppaypalpluspayment.OXORDERID = oxorder.OXID
LEFT JOIN payppaypalpluspui ON payppaypalpluspui.OXPAYMENTID = payppaypalpluspayment.OXPAYMENTID
where 1 and ( oxorder.oxfolder = 'ORDERFOLDER_NEW' )
count(*) 结果 150000
问题可能出在这个join上,其他都是立竿见影的效果
第 0 - 0 行(共 1 行,查询耗时 153.2391 秒。)
Select count(*) from `oxorder`
LEFT JOIN payppaypalpluspayment ON payppaypalpluspayment.OXORDERID = oxorder.OXID
解释
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE oxorder index NULL MAINIDX 10 NULL 146861 Using index
1 SIMPLE payppaypalpluspayment index NULL OXORDERID 32 NULL 2630 Using where; Using index; Using join buffer (flat, BNL join)
1 SIMPLE payppaypalpluspui ALL NULL NULL NULL NULL 519 Using where
在
中添加建议索引后更改
oxorder.OXPAYMENTTYPE;
oxorder.oxfolder;
payppaypalpluspui.OXPAYMENTID;
payppaypalpluspayment.OXPAYMENTID;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE oxorder ref OXFOLDER OXFOLDER 98 const 73450 Using index condition
1 SIMPLE payppaypalpluspayment ALL NULL NULL NULL NULL 2634 Using where; Using join buffer (flat, BNL join)
1 SIMPLE payppaypalpluspui ref OXPAYMENTID OXPAYMENTID 34 payppaypalpluspayment.OXPAYMENTID 1 Using where; Using index
在此计数后 selects 后端正在使用 select oxorder.* 和 payppaypalpluspui 的一列进行相同的查询(大约需要 600 秒)
UI 已经超时。当我删除最后两个连接并在服务器上手动尝试时,查询需要 < 1sec
dbs
CREATE TABLE `payppaypalpluspayment` (
`OXID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL COMMENT 'Payment oxid id',
`OXORDERID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL COMMENT 'Order id',
`OXSALEID` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment sale id',
`OXPAYMENTID` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment id',
`OXSTATUS` varchar(32) NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment status',
`OXDATECREATED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Payment creation date',
`OXTOTAL` double NOT NULL DEFAULT '0' COMMENT 'Total payment amount',
`OXCURRENCY` varchar(32) NOT NULL DEFAULT '' COMMENT 'Payment currency',
`OXPAYMENTOBJECT` blob NOT NULL COMMENT 'Serialized payment object',
PRIMARY KEY (`OXID`),
UNIQUE KEY `OXORDERID` (`OXORDERID`),
UNIQUE KEY `OXSALEID` (`OXSALEID`)
KEY `OXPAYMENTID` (`OXPAYMENTID`) <<< added this index
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='PayPal Plus payment data model'
行 3,228 InnoDB utf8_general_ci 11.4 MiB
CREATE TABLE `oxorder` (
`OXID` char(32) NOT NULL COMMENT 'Order id',
`OXSHOPID` int(11) NOT NULL DEFAULT '1' COMMENT 'Shop id (oxshops)',
`OXUSERID` char(32) NOT NULL DEFAULT '' COMMENT 'User id (oxuser)',
`OXORDERDATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Order date',
`OXORDERNR` varchar(16) NOT NULL COMMENT 'Order number',
.....
PRIMARY KEY (`OXID`),
KEY `MAINIDX` (`OXSHOPID`,`OXSTORNO`,`OXORDERDATE`),
KEY `OXORDERNR` (`OXORDERNR`)
KEY `OXPAYMENTTYPE` (`OXPAYMENTTYPE`), <<<< added this index
KEY `OXFOLDER` (`OXFOLDER`) <<<< added this index
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Shop orders information'
149,068 InnoDB utf8_general_ci 258.1 MiB
CREATE TABLE `payppaypalpluspui` (
`OXID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL COMMENT 'Payment oxid id',
`OXPAYMENTID` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment id',
`OXREFERENCENUMBER` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI reference_number',
`OXBANKNAME` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction bank name',
`OXACCOUNTHOLDER` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction account holder',
`OXIBAN` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction IBAN',
`OXBIC` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction BIC',
`OXDUEDATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'PayPal Plus PuI due date',
`OXTOTAL` double NOT NULL DEFAULT '0' COMMENT 'PayPal Plus PuI Total invoice amount',
`OXCURRENCY` varchar(32) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI invoice currency',
`OXPUIOBJECT` text NOT NULL COMMENT 'JSON representation of the payment instructions',
PRIMARY KEY (`OXID`)
KEY `OXPAYMENTID` (`OXPAYMENTID`) <<<< added this index
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='PayPal Plus Pay upon Invoice data model'
行 655 InnoDB utf8_general_ci 1.5 MiB
innodb 缓冲池 = 8 GiB
内存 10 GiB
编辑:最初我认为 LEFT Join 不相关,但理论上它们可以增加评论所指出的计数。
对于这个计数查询。所有 LEFT JOIN 似乎都不相关,因为加入的行似乎不包含比左侧 table 更多的行,并且您只检索计数,而不是其中的数据。我会删除所有这些(如果可能的话,但我现在明白情况并非如此)
对于 oxorder.* 查询。不要包括您不使用的联接。如果你总是在一对一的情况下访问加入的table
,你也会考虑更改主键
您的问题是您正在比较以不同字符集 latin1 和 utf8 编码的列。在这种情况下,索引可能不会用于键查找。您应确保对所有键列使用相同的字符集。
我最近在 Oxid 6 中安装了一个新模块 (paypal express)。0.x 后端。 安装后,我后台的后台菜单点"orders"超时了。导致查询需要的时间太长。我无法查看订单(这是 CMS 供应商资源)。
我已经尝试通过我们的托管主机支持来调试它,他们将我们的 ram 加倍以增加 mysql 缓冲区大小以及 php 超时等 php.ini.
在主机 php.ini 更改后,即使主机增加了查询缓冲区等,我仍然看到状态为 "Copying to tmp table" 的查询
问题:
我真的不确定是什么问题。有人知道我还可以尝试什么吗?
我无法想象这个小连接需要这么多缓冲区 space 和执行时间。特别是因为连接到 payppaypalpluspayment 与 oxv_oxpayments_de 相同,后者是即时的并且在相同的主键上。
这是我在进程列表
中看到 运行 的查询
显示第 0 - 0 行(总共 1 行,查询耗时 200.9683 秒。)已经从 php.ini 更改后的大约 10 分钟减少
select count(*) from `oxorder`
LEFT JOIN `oxv_oxpayments_de` AS `payments` on `payments`.oxid=oxorder.oxpaymenttype
LEFT JOIN `oxv_oxpayments_de` AS pluspayments ON pluspayments.oxid = oxorder.oxpaymenttype
LEFT JOIN payppaypalpluspayment ON payppaypalpluspayment.OXORDERID = oxorder.OXID
LEFT JOIN payppaypalpluspui ON payppaypalpluspui.OXPAYMENTID = payppaypalpluspayment.OXPAYMENTID
where 1 and ( oxorder.oxfolder = 'ORDERFOLDER_NEW' )
count(*) 结果 150000
问题可能出在这个join上,其他都是立竿见影的效果
第 0 - 0 行(共 1 行,查询耗时 153.2391 秒。)
Select count(*) from `oxorder`
LEFT JOIN payppaypalpluspayment ON payppaypalpluspayment.OXORDERID = oxorder.OXID
解释
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE oxorder index NULL MAINIDX 10 NULL 146861 Using index
1 SIMPLE payppaypalpluspayment index NULL OXORDERID 32 NULL 2630 Using where; Using index; Using join buffer (flat, BNL join)
1 SIMPLE payppaypalpluspui ALL NULL NULL NULL NULL 519 Using where
在
中添加建议索引后更改oxorder.OXPAYMENTTYPE; oxorder.oxfolder; payppaypalpluspui.OXPAYMENTID; payppaypalpluspayment.OXPAYMENTID;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE oxorder ref OXFOLDER OXFOLDER 98 const 73450 Using index condition
1 SIMPLE payppaypalpluspayment ALL NULL NULL NULL NULL 2634 Using where; Using join buffer (flat, BNL join)
1 SIMPLE payppaypalpluspui ref OXPAYMENTID OXPAYMENTID 34 payppaypalpluspayment.OXPAYMENTID 1 Using where; Using index
在此计数后 selects 后端正在使用 select oxorder.* 和 payppaypalpluspui 的一列进行相同的查询(大约需要 600 秒) UI 已经超时。当我删除最后两个连接并在服务器上手动尝试时,查询需要 < 1sec
dbs
CREATE TABLE `payppaypalpluspayment` (
`OXID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL COMMENT 'Payment oxid id',
`OXORDERID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL COMMENT 'Order id',
`OXSALEID` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment sale id',
`OXPAYMENTID` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment id',
`OXSTATUS` varchar(32) NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment status',
`OXDATECREATED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Payment creation date',
`OXTOTAL` double NOT NULL DEFAULT '0' COMMENT 'Total payment amount',
`OXCURRENCY` varchar(32) NOT NULL DEFAULT '' COMMENT 'Payment currency',
`OXPAYMENTOBJECT` blob NOT NULL COMMENT 'Serialized payment object',
PRIMARY KEY (`OXID`),
UNIQUE KEY `OXORDERID` (`OXORDERID`),
UNIQUE KEY `OXSALEID` (`OXSALEID`)
KEY `OXPAYMENTID` (`OXPAYMENTID`) <<< added this index
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='PayPal Plus payment data model'
行 3,228 InnoDB utf8_general_ci 11.4 MiB
CREATE TABLE `oxorder` (
`OXID` char(32) NOT NULL COMMENT 'Order id',
`OXSHOPID` int(11) NOT NULL DEFAULT '1' COMMENT 'Shop id (oxshops)',
`OXUSERID` char(32) NOT NULL DEFAULT '' COMMENT 'User id (oxuser)',
`OXORDERDATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Order date',
`OXORDERNR` varchar(16) NOT NULL COMMENT 'Order number',
.....
PRIMARY KEY (`OXID`),
KEY `MAINIDX` (`OXSHOPID`,`OXSTORNO`,`OXORDERDATE`),
KEY `OXORDERNR` (`OXORDERNR`)
KEY `OXPAYMENTTYPE` (`OXPAYMENTTYPE`), <<<< added this index
KEY `OXFOLDER` (`OXFOLDER`) <<<< added this index
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Shop orders information'
149,068 InnoDB utf8_general_ci 258.1 MiB
CREATE TABLE `payppaypalpluspui` (
`OXID` char(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL COMMENT 'Payment oxid id',
`OXPAYMENTID` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT '' COMMENT 'PayPal Plus payment id',
`OXREFERENCENUMBER` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI reference_number',
`OXBANKNAME` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction bank name',
`OXACCOUNTHOLDER` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction account holder',
`OXIBAN` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction IBAN',
`OXBIC` varchar(255) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI banking instruction BIC',
`OXDUEDATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'PayPal Plus PuI due date',
`OXTOTAL` double NOT NULL DEFAULT '0' COMMENT 'PayPal Plus PuI Total invoice amount',
`OXCURRENCY` varchar(32) NOT NULL DEFAULT '' COMMENT 'PayPal Plus PuI invoice currency',
`OXPUIOBJECT` text NOT NULL COMMENT 'JSON representation of the payment instructions',
PRIMARY KEY (`OXID`)
KEY `OXPAYMENTID` (`OXPAYMENTID`) <<<< added this index
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='PayPal Plus Pay upon Invoice data model'
行 655 InnoDB utf8_general_ci 1.5 MiB
innodb 缓冲池 = 8 GiB
内存 10 GiB
编辑:最初我认为 LEFT Join 不相关,但理论上它们可以增加评论所指出的计数。
对于这个计数查询。所有 LEFT JOIN 似乎都不相关,因为加入的行似乎不包含比左侧 table 更多的行,并且您只检索计数,而不是其中的数据。我会删除所有这些(如果可能的话,但我现在明白情况并非如此)
对于 oxorder.* 查询。不要包括您不使用的联接。如果你总是在一对一的情况下访问加入的table
,你也会考虑更改主键您的问题是您正在比较以不同字符集 latin1 和 utf8 编码的列。在这种情况下,索引可能不会用于键查找。您应确保对所有键列使用相同的字符集。