当我从查询中删除 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;
产品销售表定义
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;
加快查询速度的一种方法是在子查询中包含 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
分成多列是低效的。