[英]SQL query optimisation advice
我有一個奇怪的情況,幾個SQL查詢+一些簡單的php數學需要30秒鍾以上的時間才能執行。 我知道問題出在sql查詢上,但是我一生都無法想到重寫/優化查詢的方法。
通常,我會交換加入聯接,但是因為它是數學的雙重選擇,所以我想不出一種更好的方法。 我是沿着正確的路線去做這一切在查詢中還是應該做4個簡單的計數選擇並在php中進行所有數學運算。
索引建立在where子句中使用的所有列上。
查詢1
SELECT COUNT(1) FROM tblcontainergroups WHERE
(
(SELECT COUNT(1) FROM tblmovements WHERE TicketStatus=1 AND MovementType=0 AND GroupID=tblcontainergroups.ID)
-
(SELECT COUNT(1) FROM tblmovements WHERE TicketStatus=1 AND MovementType=2 AND GroupID=tblcontainergroups.ID)
)>0
查詢2
SELECT COUNT(1) FROM tblcontainergroups WHERE
(
(SELECT COUNT(1) FROM tblmovements WHERE TicketStatus=1 AND MovementType=0 AND GroupID=tblcontainergroups.ID)
-
(SELECT COUNT(1) FROM tblmovements WHERE TicketStatus=1 AND MovementType=2 AND GroupID=tblcontainergroups.ID)
)>0 AND LENGTH(DateOfIncreases)>4
然后php是這兩個數字的簡單百分比
$percentage = number_format(($total_with_increases/$total_active_groups)*100,2);
我知道這可能是一個非常簡單的問題,我可能是個白痴,但是有更好的方法嗎? 可以將查詢重寫為不是太慢了。
表結構
--
-- Table structure for table `tblcontainergroups`
--
CREATE TABLE `tblcontainergroups` (
`ID` bigint(20) unsigned NOT NULL,
`ContainerType` bigint(20) NOT NULL DEFAULT '0',
`WasteType` bigint(20) NOT NULL DEFAULT '0',
`IsHazardous` tinyint(1) NOT NULL DEFAULT '0',
`PONumber` varchar(50) DEFAULT NULL,
`SiteID` bigint(20) NOT NULL DEFAULT '0',
`CreatedBy` int(10) NOT NULL DEFAULT '0',
`CreatedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`SICProducer` varchar(500) DEFAULT NULL,
`HasRentals` tinyint(1) NOT NULL DEFAULT '0',
`DistanceText` varchar(20) DEFAULT NULL,
`DistanceMeters` int(10) NOT NULL DEFAULT '0',
`IncreaseTrans` decimal(10,2) NOT NULL DEFAULT '0.00',
`IncreaseTonnage` decimal(10,2) NOT NULL DEFAULT '0.00',
`IncreaseWLHour` decimal(10,2) NOT NULL DEFAULT '0.00',
`IncreasesCompleted` tinyint(1) NOT NULL DEFAULT '0',
`DateOfIncreases` datetime DEFAULT NULL,
`VariousWasteTypes` text,
`PremRequired` tinyint(1) NOT NULL DEFAULT '0',
`PremDescription` text
) ENGINE=InnoDB AUTO_INCREMENT=109454 DEFAULT CHARSET=latin1;
-- --------------------------------------------------------
--
-- Table structure for table `tblmovements`
--
CREATE TABLE `tblmovements` (
`ID` bigint(20) unsigned NOT NULL,
`ClientID` bigint(20) unsigned NOT NULL,
`SiteID` bigint(20) unsigned NOT NULL,
`GroupID` bigint(20) NOT NULL DEFAULT '0',
`PONumber` varchar(50) DEFAULT NULL,
`MovementType` smallint(3) NOT NULL DEFAULT '0',
`WLHours` decimal(6,2) NOT NULL DEFAULT '0.00',
`Supplier` bigint(20) NOT NULL DEFAULT '0',
`OrderedBy` varchar(200) DEFAULT NULL,
`SupplierNotes` text,
`DateRequired` datetime DEFAULT NULL,
`SuppTransCharge` decimal(10,2) NOT NULL DEFAULT '0.00',
`TransMarkup` decimal(10,2) NOT NULL DEFAULT '0.00',
`TransClientCharge` decimal(10,2) NOT NULL DEFAULT '0.00',
`SuppWeightRate` decimal(10,2) NOT NULL DEFAULT '0.00',
`WeightMarkup` decimal(10,2) NOT NULL DEFAULT '0.00',
`ClientWeightCharge` decimal(10,2) NOT NULL DEFAULT '0.00',
`SupplierIncMinTonnes` decimal(10,2) NOT NULL DEFAULT '0.00',
`ClientIncMinTonnes` decimal(10,2) NOT NULL DEFAULT '0.00',
`TonnesClientCharge` decimal(10,2) NOT NULL DEFAULT '0.00',
`TonneageType` smallint(3) NOT NULL DEFAULT '0',
`SuppWLRate` decimal(10,2) NOT NULL DEFAULT '0.00',
`WLMarkup` decimal(10,2) NOT NULL DEFAULT '0.00',
`WLClientRate` decimal(10,2) NOT NULL DEFAULT '0.00',
`CreatedBy` int(10) NOT NULL DEFAULT '0',
`CreatedOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`TicketStatus` smallint(3) NOT NULL DEFAULT '1',
`IsInvoiced` tinyint(1) NOT NULL DEFAULT '0',
`GGOrderNumber` bigint(20) NOT NULL DEFAULT '0',
`OrderSubmitted` tinyint(1) NOT NULL DEFAULT '0',
`ParentTicket` bigint(20) unsigned NOT NULL DEFAULT '0',
`SuppWLHours` decimal(5,2) NOT NULL DEFAULT '0.00',
`ClientWLHours` decimal(5,2) NOT NULL DEFAULT '0.00',
`WasteDestination` int(10) NOT NULL DEFAULT '0',
`TicketWeight` decimal(10,4) NOT NULL DEFAULT '0.0000',
`VHCReg` varchar(10) DEFAULT NULL,
`SupplierContact` varchar(200) DEFAULT NULL,
`ComplianceNotes` text,
`WeightAddedBy` int(10) NOT NULL DEFAULT '0',
`RateSetBy` int(10) NOT NULL DEFAULT '0',
`IsCompleted` tinyint(1) NOT NULL DEFAULT '0',
`DateWeightAdded` datetime DEFAULT NULL,
`RebateRate` decimal(10,2) NOT NULL DEFAULT '0.00',
`InvoiceNumber` varchar(50) DEFAULT NULL,
`IsPaid` tinyint(1) NOT NULL DEFAULT '0',
`InvoiceDate` datetime DEFAULT NULL,
`ActualRebate` decimal(20,2) NOT NULL DEFAULT '0.00',
`RebateToClient` decimal(10,2) NOT NULL DEFAULT '0.00',
`SupplierWeightContact` varchar(200) DEFAULT NULL,
`VHCAddedBy` int(10) NOT NULL DEFAULT '0',
`OldTicketNumber` varchar(20) DEFAULT NULL,
`BelongsToWR` bigint(20) NOT NULL DEFAULT '0',
`OkInvoice` tinyint(1) NOT NULL DEFAULT '0',
`DeletionDate` datetime DEFAULT NULL,
`DeletedBy` int(10) NOT NULL DEFAULT '0',
`SupplierInvNo` varchar(100) DEFAULT NULL,
`SuppTicketNo` varchar(100) DEFAULT NULL,
`SuppIsDisputed` tinyint(1) NOT NULL DEFAULT '0',
`SuppDateDisputed` datetime DEFAULT NULL,
`SuppDisputedBy` int(10) NOT NULL DEFAULT '0',
`SuppDateDisputeCleared` datetime DEFAULT NULL,
`SuppDisputeClearedBy` int(10) NOT NULL DEFAULT '0',
`SuppIsPaid` tinyint(1) NOT NULL DEFAULT '0',
`SuppPaidOn` datetime DEFAULT NULL,
`SuppPaidBy` int(10) NOT NULL DEFAULT '0',
`TicketApproveReason` text,
`ComplianceCopyTicket` tinyint(1) NOT NULL DEFAULT '0',
`SuppInvCheckedBy` int(10) NOT NULL DEFAULT '0',
`SuppCheckDate` datetime DEFAULT NULL,
`SupplierOrderConfirmedBy` text,
`OrderConfirmationDate` datetime DEFAULT NULL,
`OrderConfirmedUser` int(10) NOT NULL DEFAULT '0',
`TicketReceived` tinyint(1) NOT NULL DEFAULT '0',
`DisputeReason` text,
`DisputeType` smallint(5) NOT NULL DEFAULT '0',
`DisputeClearReason` text,
`ClientIsDisputed` tinyint(1) NOT NULL DEFAULT '0',
`ClientDateDisputed` datetime DEFAULT NULL,
`ClientDisputedBy` int(10) NOT NULL DEFAULT '0',
`ClientDisputeReason` text,
`ClientDisputeType` smallint(5) NOT NULL DEFAULT '0',
`ClientDateDisputeCleared` datetime DEFAULT NULL,
`ClientDisputeClearedBy` int(10) NOT NULL DEFAULT '0',
`ClientDisputeClearReason` text,
`CarbonUsageKGKM` decimal(20,4) NOT NULL DEFAULT '0.0000',
`CarbonUsageKGL` decimal(20,4) NOT NULL DEFAULT '0.0000',
`SuppTonneageType` smallint(3) NOT NULL DEFAULT '0',
`TicketApprovedBy` int(10) NOT NULL DEFAULT '0',
`TicketApprovedDate` datetime DEFAULT NULL,
`IsLate` tinyint(1) NOT NULL DEFAULT '0',
`RoRoProcessed` tinyint(1) NOT NULL DEFAULT '0',
`LeadOwnerBDM` int(10) NOT NULL DEFAULT '0',
`LastComplianceUpdate` datetime DEFAULT NULL,
`IsDummy` tinyint(4) DEFAULT '0',
`DisputerName` text,
`DisputerContact` text,
`ClientDisputerName` text,
`ClientDisputerContact` text,
`MarginsProcessed` tinyint(1) NOT NULL DEFAULT '0',
`OrigCreator` int(10) NOT NULL DEFAULT '0',
`AccountsSent` tinyint(1) NOT NULL DEFAULT '0',
`NoRebate` tinyint(1) NOT NULL DEFAULT '0',
`WTNCreated` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB AUTO_INCREMENT=368401 DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `tblcontainergroups`
--
ALTER TABLE `tblcontainergroups`
ADD PRIMARY KEY (`ID`), ADD KEY `ContainerType` (`ContainerType`), ADD KEY `WasteType` (`WasteType`);
--
-- Indexes for table `tblmovements`
--
ALTER TABLE `tblmovements`
ADD PRIMARY KEY (`ID`), ADD KEY `ClientID` (`ClientID`), ADD KEY `SiteID` (`SiteID`), ADD KEY `GroupID` (`GroupID`), ADD KEY `Supplier` (`Supplier`), ADD KEY `OrderedBy` (`OrderedBy`), ADD KEY `CreatedBy` (`CreatedBy`), ADD KEY `GGOrderNumber` (`GGOrderNumber`), ADD KEY `WasteDestination` (`WasteDestination`), ADD KEY `WeightAddedBy` (`WeightAddedBy`), ADD KEY `RateSetBy` (`RateSetBy`), ADD KEY `VHCAddedBy` (`VHCAddedBy`), ADD KEY `BelongsToWR` (`BelongsToWR`), ADD KEY `DeletedBy` (`DeletedBy`), ADD KEY `SupplierInvNo` (`SupplierInvNo`), ADD KEY `SuppDisputedBy` (`SuppDisputedBy`), ADD KEY `SuppDisputeClearedBy` (`SuppDisputeClearedBy`), ADD KEY `SuppPaidBy` (`SuppPaidBy`), ADD KEY `SuppInvCheckedBy` (`SuppInvCheckedBy`), ADD KEY `OrderConfirmedUser` (`OrderConfirmedUser`), ADD KEY `DisputeType` (`DisputeType`), ADD KEY `TicketApprovedBy` (`TicketApprovedBy`), ADD KEY `ClientDisputeClearedBy` (`ClientDisputeClearedBy`), ADD KEY `ClientDisputedBy` (`ClientDisputedBy`), ADD KEY `LeadOwnerBDM` (`LeadOwnerBDM`), ADD KEY `m_disputed` (`SuppIsDisputed`), ADD KEY `m_clientdisputed` (`ClientIsDisputed`), ADD KEY `OrigCreator` (`OrigCreator`), ADD KEY `TicketStatus` (`TicketStatus`), ADD KEY `MovementType` (`MovementType`);
這可能是一個簡單的問題,但是對我來說很難,因為我看不到您要構建的模型邏輯。
不過,根據我的說法,以下應該是查詢的優化版本:
SELECT COUNT(1)
FROM tblcontainergroups
WHERE (SELECT SUM(IF(MovementType=0,1,IF(MovementType=2, -1, 0)))
FROM tblmovements
WHERE GroupID=tblcontainergroups.ID AND TicketStatus=1)>0
基本上,您僅需要一個帶有條件SUM的子查詢,該子查詢將根據MovementType值以及GroupID和TicketStatus的子查詢條件求和為1或-1。
另外,您需要為tblmovements表中的GroupID,MovementType和TicketStatus字段分別創建索引。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.