MySQL 查询使用 SUM 和 GROUP BY 花费太多时间

问题描述 投票:0回答:1

当我从查询中删除 sum 和 group by 部分时,时间显着减少到 1 秒以下。

执行上面的查询需要2分钟,除了tender表有大约100条记录外,每个表只有95000行。我该如何优化这个查询?

相关索引已创建,我已将它们链接在底部

'' = '' 或 TT.Currency_Id ='' 是占位符

执行查询如下。

select
        RTI.Terminal_Number as TERMINAL_NUMBER,
        RTI.Transaction_Number as TRANSACTION_NUMBER,
        RTI.Completed_Date_Time as DATE_TIME,
        PS.User_Id as USER_ID,
        TT.Customer_Id as CUSTOMER_ID,
        TT.Customer_Surname as CUSTOMER_SURNAME,
        T.Description as TENDER_TYPE,
        sum(PS.Sales_Quantity) as SALES_QUANTITY,
        sum(-PS.Returns_Quantity) as RETURNS_QUANTITY,
        sum(-TT.Value) as VALUE,
        sum(PS.Sales_Value) as SALES_VALUE,
        sum(-PS.Returns_Value) as RETURNS_VALUE,
        sum(PS.Tax_Value) as TAX_VALUE,
        TT.Card_Number_Mangled as CARD_NUMBER
from
        ProductSales PS
inner join RetailTransactionIds RTI on
        PS.Transaction_Key = RTI.Transaction_Key
inner join TenderTransactions TT on
        TT.Transaction_Key = RTI.Transaction_Key
inner join Tenders T on
        T.Tender_Id = TT.Tender_Id
        and T.Group_Id=TT.Tender_Group_Id
        and T.Group_Hierarchy_Id=TT.Tender_Group_Hierarchy_Id
where
        ('' = ''
        or TT.Currency_Id ='')
        and ('' = ''
        or RTI.Location_Id ='')
        and ('' = ''
        or PS.User_Id = '')
        and ('' = ''
        or RTI.Device_Id ='')
        and ('' = ''
        or TT.Tender_Id = '')
        and ('' = ''
        or TT.Customer_Id = '')
        and ('' = ''
        or TT.Card_Number = '')
        and ('' = ''
        or TT.Card_Scheme_Id = '')
group by
        RTI.Terminal_Number,
        RTI.Transaction_Number,
        RTI.Completed_Date_Time,
        TT.Customer_Id,
        TT.Customer_Surname,
        T.Description,
        TT.Card_Number_Mangled,
        PS.User_Id,
        PS.Sales_Quantity;

产品销售表索引

Productsale table indexes

retailTransactionId 表索引

retailTransactionId table indexes

投标交易表索引

tendertransaction table indexes

对查询进行解释

Explain on the query

产品销售表定义

CREATE TABLE `productsales` (
  `Entity_Name` varchar(255) CHARACTER SET utf8 NOT NULL,
  `Last_Updated` datetime DEFAULT NULL,
  `Transaction_Key` varchar(44) CHARACTER SET utf8 DEFAULT NULL,
  `Line_Number` int(11) DEFAULT NULL,
  `User_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Salesperson_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Date_Number` int(11) DEFAULT NULL,
  `Year` int(11) DEFAULT NULL,
  `Day` int(11) DEFAULT NULL,
  `Hour` tinyint(4) DEFAULT NULL,
  `Minute` tinyint(4) DEFAULT NULL,
  `Product_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Product_Description` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `MMGroup_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `MMGroup_Hierarchy_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `MMGroup_Variant_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `MMGroup_Variant_Hierarchy_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Sales_Value` bigint(20) DEFAULT NULL,
  `Sales_Quantity` double DEFAULT NULL,
  `Discounts_Value` bigint(20) DEFAULT NULL,
  `Promotions_Value` bigint(20) DEFAULT NULL,
  `Price_Overrides_Value` bigint(20) DEFAULT NULL,
  `Returns_Value` bigint(20) DEFAULT NULL,
  `Returns_Quantity` double DEFAULT NULL,
  `Tax_Value` bigint(20) DEFAULT NULL,
  `Tax_Exempt_Value` bigint(20) DEFAULT NULL,
  `Tax_Exempt_Reason_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Values_Include_Tax` tinyint(1) DEFAULT NULL,
  `Tax_Rate_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Tax_Rate_Effective_Date` datetime DEFAULT NULL,
  `Receipt_Return` tinyint(1) DEFAULT NULL,
  `Reference_Number` varchar(512) CHARACTER SET utf8 DEFAULT NULL,
  `Price_Change_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Item_Type` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Orders_Value` bigint(20) DEFAULT NULL,
  `Orders_Quantity` double DEFAULT NULL,
  `Tender_Description` varchar(40) DEFAULT NULL,
  UNIQUE KEY `productsales_Transaction_Key_desc_IDX` (`Transaction_Key`,`Line_Number`,`Tender_Description`) USING BTREE,
  KEY `ProductSalesIdDescIndex` (`Product_Id`,`Product_Description`),
  KEY `ProductSalesDateNumberIndex` (`Date_Number`),
  KEY `productsales_Transaction_Key_IDX` (`Transaction_Key`) USING BTREE,
  KEY `productsales_User_Id_IDX` (`User_Id`,`Sales_Quantity`) USING BTREE,
  KEY `productsales_Tender_Description_IDX` (`Tender_Description`) USING BTREE,
  KEY `productsales_Sales_Value_IDX` (`Sales_Value`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

产品销售表定义

CREATE TABLE `retailtransactionids` (
  `Entity_Name` varchar(255) CHARACTER SET utf8 NOT NULL,
  `Last_Updated` datetime DEFAULT NULL,
  `Transaction_Key` varchar(44) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Transaction_Number` bigint(20) DEFAULT NULL,
  `Location_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Terminal_Number` bigint(20) DEFAULT NULL,
  `Device_Id` varchar(40) CHARACTER SET utf8 DEFAULT NULL,
  `Region_Group_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Region_Group_Hierarchy_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Transaction_Id` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `Application_Id` varchar(40) CHARACTER SET utf8 DEFAULT NULL,
  `Base_Currency_Id` varchar(3) CHARACTER SET utf8 DEFAULT NULL,
  `Completed_Date_Time` datetime DEFAULT NULL,
  `Completed_Day` int(11) DEFAULT NULL,
  `Completed_Year` int(11) DEFAULT NULL,
  `Completed_Date_Number` int(11) DEFAULT NULL,
  `Completed_Trading_Day` int(11) DEFAULT NULL,
  `Completed_Trading_Year` int(11) DEFAULT NULL,
  `Created_Date_Time` datetime DEFAULT NULL,
  `Created_Day` int(11) DEFAULT NULL,
  `Created_Year` int(11) DEFAULT NULL,
  `Created_Date_Number` int(11) DEFAULT NULL,
  `Created_Trading_Day` int(11) DEFAULT NULL,
  `Created_Trading_Year` int(11) DEFAULT NULL,
  UNIQUE KEY `RetailTransactionIdsKeyIndex` (`Transaction_Key`),
  KEY `RetailTransactionIdsAppTrans` (`Application_Id`,`Transaction_Id`),
  KEY `RetailTransIdsTransIdIdx` (`Transaction_Id`),
  KEY `Retailtransids_Locatedate` (`Location_Id`,`Completed_Date_Time`),
  KEY `RetailTransIdsComplteAndLocId` (`Completed_Date_Time`,`Location_Id`),
  KEY `RetailTransIds_Session` (`Location_Id`,`Terminal_Number`,`Completed_Date_Time`),
  KEY `retailtransactionids_Terminal_Number_IDX` (`Terminal_Number`,`Transaction_Number`,`Completed_Date_Time`) USING BTREE,
  KEY `retailtransactionids_TermNum_TranNum_IDX` (`Terminal_Number`,`Transaction_Number`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

TenderTransactions 表定义

CREATE TABLE `tendertransactions` (
  `Entity_Name` varchar(255) CHARACTER SET utf8 NOT NULL,
  `Last_Updated` datetime DEFAULT NULL,
  `Transaction_Key` varchar(44) CHARACTER SET utf8 DEFAULT NULL,
  `Line_Number` int(11) DEFAULT NULL,
  `Year` int(11) DEFAULT NULL,
  `Day` int(11) DEFAULT NULL,
  `Date_Number` int(11) DEFAULT NULL,
  `Hour` tinyint(4) DEFAULT NULL,
  `Minute` tinyint(4) DEFAULT NULL,
  `Tender_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Tender_Group_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Tender_Group_Hierarchy_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Tender_Type` varchar(40) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Currency_Id` varchar(3) CHARACTER SET utf8 DEFAULT NULL,
  `Base_Value` bigint(20) DEFAULT NULL,
  `Value` bigint(20) DEFAULT NULL,
  `Exchange_Rate` double DEFAULT NULL,
  `User_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Authorising_User_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Card_Number` varchar(22) CHARACTER SET utf8 DEFAULT NULL,
  `Card_Number_Hashed` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
  `Card_Number_Mangled` varchar(44) CHARACTER SET utf8 DEFAULT NULL,
  `Encrypted_Data` varchar(350) CHARACTER SET utf8 DEFAULT NULL,
  `Key_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Card_Type_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Card_Type_Group_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Card_Type_Group_Hierarchy_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Customer_Id` varchar(44) CHARACTER SET utf8 DEFAULT NULL,
  `Customer_Surname` varchar(100) CHARACTER SET utf8 DEFAULT NULL,
  `Customer_Postcode` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Merchant_Id` varchar(15) CHARACTER SET utf8 DEFAULT NULL,
  `Acquirer_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Acquirer_Group_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Acquirer_Group_Hierarchy_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  `Is_Change` tinyint(1) DEFAULT NULL,
  `Account_Id` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
  `Surcharge_Value` bigint(20) DEFAULT NULL,
  `Over_Payment_Amount` bigint(20) DEFAULT NULL,
  `Card_Entry_Method` varchar(5) CHARACTER SET utf8 DEFAULT NULL,
  `Coupon_Manufacturer_Id` varchar(15) CHARACTER SET utf8 DEFAULT NULL,
  `Coupon_Manufacturer_Ref_Id` varchar(10) CHARACTER SET utf8 DEFAULT NULL,
  `Card_Scheme_Id` varchar(20) CHARACTER SET utf8 DEFAULT NULL,
  UNIQUE KEY `TenderTransactionsKeyIndex` (`Transaction_Key`,`Line_Number`),
  KEY `TenderTransCardNumberIndex` (`Card_Number`),
  KEY `TenderTransCardNumberHashIndex` (`Card_Number_Hashed`),
  KEY `TenderTransBaseValueIndex` (`Base_Value`),
  KEY `TenderTransUserIdIndex` (`User_Id`),
  KEY `TenderTransCustomerIdIndex` (`Customer_Id`),
  KEY `TenderTransValueIndex` (`Value`),
  KEY `TenderTransDateNumber` (`Date_Number`),
  KEY `tendertransactions_Transaction_Key_IDX` (`Transaction_Key`) USING BTREE,
  KEY `tendertransactions_Customer_Id_IDX` (`Customer_Id`,`Customer_Surname`,`Card_Number_Mangled`) USING BTREE,
  KEY `tendertransactions_Tender_Id_IDX` (`Tender_Id`,`Tender_Group_Id`,`Tender_Group_Hierarchy_Id`) USING BTREE,
  KEY `tendertransactions_covering_IDX` (`Transaction_Key`,`Tender_Id`,`Tender_Group_Id`,`Tender_Group_Hierarchy_Id`) USING BTREE,
  KEY `tendertransactions_Currency_Id_IDX` (`Currency_Id`,`Tender_Id`,`Customer_Id`,`Card_Number`,`Card_Scheme_Id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

投标表定义

CREATE TABLE `tenders` (
  `ID` varchar(44) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Entity_Name` varchar(255) CHARACTER SET utf8 NOT NULL,
  `Tender_Id` varchar(20) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Tender_Type` varchar(40) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Description` varchar(40) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Group_Id` varchar(20) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Group_Type` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Group_Hierarchy_Id` varchar(20) CHARACTER SET utf8 NOT NULL DEFAULT '-',
  `Is_Auto_Banked` tinyint(1) DEFAULT NULL,
  `Is_Auto_Picked_Up` tinyint(1) DEFAULT NULL,
  `Is_Banking_Tender` tinyint(1) DEFAULT NULL,
  `Is_Cashup_Tender` tinyint(1) DEFAULT NULL,
  `Is_Currency_Purchase_Tender` tinyint(1) DEFAULT NULL,
  `Is_Float_Tender` tinyint(1) DEFAULT NULL,
  `Is_Pickup_Tender` tinyint(1) DEFAULT NULL,
  `Is_Spot_Check_Tender` tinyint(1) DEFAULT NULL,
  `Timestamp` bigint(20) NOT NULL DEFAULT '0',
  `Last_Updated` datetime DEFAULT NULL,
  `XML` longtext NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `TendersKeyIndex` (`Tender_Id`,`Group_Id`,`Group_Type`,`Group_Hierarchy_Id`),
  KEY `TendersTenderTypeIndex` (`Tender_Type`),
  KEY `TendersUpdatedIndex` (`Last_Updated`),
  KEY `TendersTimestampIndex` (`Timestamp`),
  KEY `tenders_Tender_Id_IDX` (`Tender_Id`,`Group_Id`,`Group_Hierarchy_Id`) USING BTREE,
  KEY `tenders_Description_IDX` (`Description`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
mysql group-by sum query-optimization
1个回答
0
投票

加快查询速度的一种方法是在子查询中包含 3 个表,然后在执行完

T.Description as TENDER_TYPE
后查找
GROUP BY
,如下所示:

SELECT subq.*, T.Description as TENDER_TYPE
    FROM (
        select  RTI.Terminal_Number as TERMINAL_NUMBER, RTI.Transaction_Number as TRANSACTION_NUMBER,
                RTI.Completed_Date_Time as DATE_TIME, PS.User_Id as USER_ID,
                TT.Customer_Id as CUSTOMER_ID, TT.Customer_Surname as CUSTOMER_SURNAME,
                T.Description as TENDER_TYPE, sum(PS.Sales_Quantity) as SALES_QUANTITY,
                sum(-PS.Returns_Quantity) as RETURNS_QUANTITY, sum(-TT.Value) as VALUE,
                sum(PS.Sales_Value) as SALES_VALUE, sum(-PS.Returns_Value) as RETURNS_VALUE,
                sum(PS.Tax_Value) as TAX_VALUE, TT.Card_Number_Mangled as CARD_NUMBER
            from  ProductSales PS
            inner join  RetailTransactionIds RTI  ON PS.Transaction_Key = RTI.Transaction_Key
            inner join  TenderTransactions TT  ON TT.Transaction_Key = RTI.Transaction_Key
            inner join  Tenders T  ON T.Tender_Id = TT.Tender_Id
              and  T.Group_Id=TT.Tender_Group_Id
              and  T.Group_Hierarchy_Id=TT.Tender_Group_Hierarchy_Id
            where  ...
            group by  RTI.Terminal_Number, RTI.Transaction_Number, RTI.Completed_Date_Time,
                TT.Customer_Id, TT.Customer_Surname, TT.Card_Number_Mangled,
                PS.User_Id, PS.Sales_Quantity
      ) AS subq
    JOIN Tenders T  ON T.Tender_Id = subq.Tender_Id
              and  T.Group_Id = subq.Tender_Group_Id
              and  T.Group_Hierarchy_Id = subq.Tender_Group_Hierarchy_Id

如果数据远大于

innodb_buffer_pool_size
,则可能存在缓存问题。 (上面的重写会有所帮助。)

许多列的数据类型大于所需的数据类型。

WHERE
子句很奇怪——
('' = '' OR ...)
总是
TRUE
;希望优化器足够聪明,能够意识到这一点。

您的其中一张桌子上没有

PRIMARY KEY
。 它确实有一个
UNIQUE
键,但无法将其提升为
PRIMARY
,因为列是
NULLable

通常

DATETIME
分成多列是低效的。

© www.soinside.com 2019 - 2024. All rights reserved.