【问题标题】:MySQL multiple Sending Data statesMySQL 多个 Sending Data 状态
【发布时间】:2018-02-07 20:23:45
【问题描述】:

我的查询运行时间过长。当我对其进行分析时,我会看到类似的内容:

    Sending data    0.039324
    executing   0.000011
    Sending data    0.039662
    executing   0.000012
    Sending data    0.040380
    executing   0.000015
    Sending data    0.035879
    executing   0.000012
    Sending data    0.035426
    executing   0.000012
    Sending data    0.038107
    executing   0.000011
    Sending data    0.035247
    executing   0.000011
    Sending data    0.050108
    executing   0.000014
    Sending data    0.045458
    executing   0.000012
    Sending data    0.034700
    executing   0.000012
    Sending data    0.036205
    executing   0.000012
    Sending data    0.034602
    executing   0.000015
    Sending data    0.034580
    executing   0.000012
    Sending data    0.034477
    executing   0.000010
    Sending data    0.034382
    executing   0.000010
    Sending data    0.034416
    executing   0.000011
    Sending data    0.034335
    executing   0.000010
    Sending data    0.034474
    executing   0.000010
    Sending data    0.034405
    executing   0.000010
    Sending data    0.034433
    executing   0.000011
    Sending data    0.034544
    executing   0.000010
    Sending data    0.034525
    executing   0.000011
    Sending data    0.034459
    executing   0.000010
    Sending data    0.034766
    executing   0.000011
    Sending data    0.034633
    executing   0.000010
    Sending data    0.034574
    executing   0.000011
    Sending data    0.034607
    executing   0.000010
    Sending data    0.034613
    executing   0.000011
    Sending data    0.034394
    executing   0.000010
    Sending data    0.034606
    executing   0.000011
    Sending data    0.034790
    executing   0.000011
    Sending data    0.034614
    executing   0.000011
    Sending data    0.034497
    executing   0.000010
    Sending data    0.034756
    executing   0.000010
    Sending data    0.034440
    executing   0.000010
    Sending data    0.034414
    executing   0.000011
    Sending data    0.034484
    executing   0.000011
    Sending data    0.034490
    executing   0.000011
    Sending data    0.034672
    executing   0.000011
    Sending data    0.034455
    executing   0.000011
    Sending data    0.034430
    executing   0.000011
    Sending data    0.034509
    executing   0.000012
    Sending data    0.034432
    executing   0.000012
    Sending data    0.034348
    executing   0.000011
    Sending data    0.034378
    executing   0.000011
    Sending data    0.034356
    executing   0.000011
    Sending data    0.034631
    end 0.000014
    query end   0.000007
    closing tables  0.000010
    freeing items   0.000025
    logging slow query  0.000003
    logging slow query  0.000004
    cleaning up 0.000004

里面发送的数据太多了。

我运行的查询:

SELECT COUNT(*) as count from OrdersArchive where ID>0 and PId IN ('2564') and 
   (
   ID like '17000106864' 
   OR `OrderID` like '17000106864' 
   OR `ID` IN
   (
       SELECT `transferID`
       FROM `custom_fields`
       WHERE `fieldName` = 'invoiceNumber'
       AND `value` like '%17000106864%'
   )
   OR `tpb` LIKE '17000106864' 

   )

解释节目

id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY OrdersArchive 范围 PRIMARY,ID_UNIQUE PRIMARY 4 NULL 41609 使用 where 2 DEPENDENT SUBQUERY custom_fields ALL NULL NULL NULL NULL 93141 使用 where

MySQL 表结构:

如果不存在 `OrdersArchive` 则创建表( `ID` int(11) NOT NULL, `ids` int(11) NOT NULL DEFAULT '0', `OrderID` varchar(11) NOT NULL DEFAULT '0', `PricePosition` int(11) NOT NULL DEFAULT '0', `Reverse` tinyint(1) 默认为空, `DataOrder` 时间戳 NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `DataFlightTrain` 时间戳 NOT NULL DEFAULT '0000-00-00 00:00:00', `客户` varchar(255) 默认为空, `PhoneCustomer` varchar(255) 默认为空, `EmailCustomer` varchar(255) 默认为空, `Provider` int(11) 默认为空, `DeliveryTime` 时间戳 NULL DEFAULT NULL, `Address1` varchar(255) 默认为 NULL, `Address2` varchar(255) NOT NULL, `Passangers` varchar(1024) 默认为空, `PassangersPhones` varchar(255) NOT NULL, `PassangersEmailes` varchar(255) NOT NULL, `FlightTrain` varchar(255) 默认为空, `QuantityPassangers` int(11) 默认 '1', `NamePlate` varchar(255) 默认为空, `PhoneDriver` varchar(255) 默认为空, `PhoneDriverNeed` tinyint(1) 默认 '0', `状态` int(11) 默认为空, `Operator` int(11) 默认为空, `userId` int(11) 非空, `usn` varchar(256) NOT NULL, `ArendaNeed` varchar(255) DEFAULT '', `ArendaHour` int(11) 默认为空, `ArendaMinutes` varchar(255) DEFAULT '', `Cost` 双 DEFAULT NULL, `Notes` 文本不为空, `notes2` varchar(256) NOT NULL DEFAULT '', `PId` int(11) NOT NULL DEFAULT '0', `凭证` varchar(256) NOT NULL, `Invoice` varchar(256) NOT NULL, `Meet` varchar(255) NOT NULL, `Toward` varchar(255) NOT NULL, `techStatus` int(2) NOT NULL DEFAULT '0', `City` varchar(55) NOT NULL, `City2` varchar(55) 非空, `Auto` varchar(30) NOT NULL, `department` varchar(255) NOT NULL DEFAULT '', `nsktime` 时间戳 NOT NULL DEFAULT '0000-00-00 00:00:00', `tpb` varchar(255) NOT NULL DEFAULT '', `ban_add_races` int(1) NOT NULL DEFAULT '0', `paid` int(10) NOT NULL DEFAULT '0', `taxi` varchar(255) NOT NULL DEFAULT '', `price_client` int(11) 默认为空, `commission_from_client` int(11) 默认为 NULL, `primechanie` varchar(1000) 默认为空, 主键(`ID`), 唯一键`ID_UNIQUE`(`ID`), KEY `fk_Orders_Users1_idx`(`Operator`), KEY `fk_Orders_Providers1_idx`(`Provider`), KEY `fk_Orders_OrderStatus1_idx`(`状态`), KEY `ids` (`ids`) ) 引擎=InnoDB 默认字符集=utf8; ##和其他表 如果不存在 `custom_fields` 则创建表( `ID` int(11) NOT NULL AUTO_INCREMENT, `pid` int(11) NOT NULL, `transferID` int(11) NOT NULL, `fieldName` varchar(255) NOT NULL, `value` varchar(1024) NOT NULL, 主键(`ID`) ) 引擎=InnoDB 默认字符集=utf8 AUTO_INCREMENT=325452 ;

【问题讨论】:

  • 您缺少一些索引,例如OrdersArchive 平板电脑中的OrderID 和tpb。 custom_fields 表总是效率很低。无论如何,我假设您希望您的查询运行得更快,快多少?不要忘记运行查询的平台也会影响速度。
  • 添加了您提到的索引,但查询2分钟之类的结果仍然很糟糕。从查询中删除子查询确实可以将性能提高到近 0.1 秒
  • 子查询返回单个结果,因此不必是子查询。我不希望 MySQL 会为OrdersArchive 的每一行运行它,但它可能会。由于您使用的是 PHP,因此请先尝试执行子查询,然后使用 PHP 生成OR ID IN (.....),这样它将是一个恒定的 ID 数组。可以有多少张发票?
  • AND value like '%17000106864%' 这很慢,因为 '%...' 不能使用索引
  • 我正在尝试重写查询以使用 JOIN,但现在它发送计数 = 2,但实际计数为 1。查询:SELECT DISTINCT COUNT(*) as count FROM OrdersArchive INNER JOIN custom_fields在 OrdersArchive.ID = custom_fields.transferID WHERE OrdersArchive.ID>0 AND OrdersArchive.PId IN ('2564') AND ( OrdersArchive.ID LIKE '17000106864' OR OrdersArchive.OrderID LIKE '17000106864' OR OrdersArchive。 tpb LIKE '17000106864' 或(custom_fields.fieldName = 'invoiceNumber' AND custom_fields.value like '%17000106864%'))

标签: php mysql profiling entity-attribute-value explain


【解决方案1】:

虽然当前的 SELECT 查询可能会在一定程度上得到改进,但我认为如果您能够以更有效的方式存储数据,尤其是如果您可以消除对

AND value 喜欢 '%17000106864%'

如果您为 invoiceNumber 创建一个单独的字段并在插入数据时填充它,您可以将其编入索引并像这样选择/加入它:

WHERE invoiceNumber=17000106864

如果您只查找一条​​记录,在查询中添加 LIMIT 也会有所帮助。

【讨论】:

    【解决方案2】:

    嗯,我通过 INNER JOIN 完成了这个。运行 0.34 秒

    最终查询是:

    选择 COUNT(`OrdersArchive`.ID) 作为计数,`OrdersArchive`.ID 来自“订单存档” `OrdersArchive`.ID = `custom_fields`.`transferID` 上的 INNER JOIN `custom_fields` WHERE `OrdersArchive`.ID>0 AND `custom_fields`.`fieldName` = 'invoiceNumber' 和 `OrdersArchive`.PId IN ('2564') AND ( `OrdersArchive`.ID LIKE '17000106864' OR `OrdersArchive`.`OrderID` LIKE '17000106864' 或 `OrdersArchive`.`tpb` LIKE '17000106864' 要么 ( `custom_fields`.`value` 像 '%17000106864%' ) )

    【讨论】:

      【解决方案3】:

      回到标题中隐含的问题(“多个发送数据状态”)...

      IN(SELECT ...) 通常效率很低。在您的情况下,它被重复执行,从而为每次调用“执行”和“发送数据”。

      其他答案通过将该构造转换为JOIN 来解决其他隐含的问题(“查询运行时间过长”)。

      其他问题;

      PRIMARY KEY (`ID`),   -- This is UNIQUE and an INDEX
      UNIQUE KEY `ID_UNIQUE` (`ID`),  -- totally redundant; DROP it
      

      您可能受到性能问题的困扰,因为架构是“EAV”(实体-属性-值),您需要根据一些键值(“invoiceNumber”)进行过滤。考虑将其从键值表(custom_fields)中拉出并放入主表(OrdersArchive)中。

      但后来我看到OrdersArchive 有相当多的列。但我对此没有任何具体建议。

      custom_fields 完全没有索引。请参阅my tips 索引公共键值表。

      【讨论】:

        猜你喜欢
        • 2011-03-31
        • 2013-01-25
        • 1970-01-01
        • 1970-01-01
        • 2015-09-12
        • 1970-01-01
        • 1970-01-01
        • 2012-09-13
        • 2019-06-29
        相关资源
        最近更新 更多