2016-02-05 131 views
0

我有一個奇怪的情況,其中一些SQL查詢+一些簡單的PHP數學正在花費30秒以上+執行。我知道問題在於SQL查詢,但我不能爲我的生活想到重寫/優化查詢的方法。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是那些2個數字

$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`); 

回答

2

這可能是一個簡單的問題,但它是對我來說很難,因爲我看不到你正在試圖建立模型的邏輯。

不過,下面的應該是你查詢的優化版本,根據我:

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 

基本上,你只需要與條件的總和一個子查詢,將總結1S或-1s根據MovementType值,以及GroupID和TicketStatus的子查詢條件。

此外,您需要爲tblmovements表中的GroupID,MovementType和TicketStatus字段(單獨)創建索引。

+0

它們都已被索引。邏輯就是我試圖找到一個容器組的百分比增加在查詢2中應用'LENGTH(DateOfIncreases)> 4'與活動容器組的數量,即:query1。如果有更多的交付,那麼容器組被認爲是活動的,而刪除是每個查詢的子選擇部分:)。我避免了IF語句路由,因爲我認爲IF會比2個簡單的子選擇計數更耗資源。我會試試看看它的行爲如何。 – Dave

+0

因此,應用你的版本,它並沒有真正使它快得多 – Dave

+0

戴夫,我想知道如何優化這個查詢,使其更快。是否有可能向我發送的數據僅包含不會導致敏感數據共享問題的必要字段,因此我可以在我的環境中查看它? – smozgur