SQL查询优化建议

时间:2016-02-05 10:51:32

标签: php mysql

我有一个奇怪的情况,一些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`);

1 个答案:

答案 0 :(得分: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

基本上,您只需要一个带有条件SUM的子查询,它将根据MovementType值加1s或-1s,以及GroupID和TicketStatus的子查询条件。

此外,您需要在tblmovements表中为GroupID,MovementType和TicketStatus字段(单独)创建索引。