查询性能调试

时间:2018-11-08 10:00:34

标签: php mysql database-performance

我最近在Oxid 6.0.x后端安装了一个新模块(贝宝快递)。 安装后,我后端的后端菜单点“ orders”正在超时。导致查询需要太长时间。我无法查看订单(这是CMS供应商资源)。

我已经尝试通过托管托管人支持对其进行调试,后者将ram翻了一番,以增加php.ini中的mysql缓冲区大小以及php timouts等。

更改托管人php.ini之后,即使托管人增加了查询缓冲区等,我仍然看到状态为“正在复制到tmp表”的查询。

问题:
我真的不确定是什么问题。有人对我还有什么想法可以尝试吗? 我无法想象这一个小的联接需要那么多的缓冲空间和执行时间。特别是由于对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
问题可能是这种加入,其他都是即时结果
第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

选择此计数后,后端使用select oxorder。*和payppaypalpluspui中的一列进行相同的查询(大约需要600秒) 然后,UI已超时。当我删除最后两个联接并在服务器上手动尝试时,查询需要<1秒

数据库

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'

第3228行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

2 个答案:

答案 0 :(得分:3)

您的问题是,您正在比较以不同字符集latin1和utf8编码的列。在这种情况下,索引可能不会用于键查询。您应该确保所有键列都使用相同的字符集。

答案 1 :(得分:0)

编辑:最初我认为LEFT Join的关系不大,但从理论上讲,它们可以增加评论所指出的数量。

对于此计数查询。所有的LEFT JOIN似乎都是无关紧要的,因为联接似乎不包含比左表更多的行,并且您仅检索计数,而不检索其中的数据。我将全部删除(如果可能的话,但我现在知道不是这种情况)

对于oxorder。*查询。不包括不使用的联接。另外,如果您总是在一对一的情况下访问联接的表,那么您会考虑更改主键