我有几个表,目的是确定“最佳”,即单个项目或一组这些项目将适合的最小方框。 只是为了让我“足够接近”,这样我才能确定不同承运人的该商品的运输成本。
我将两个步骤结合在一起:1通过MySQl查询获取每个项目及其测量值,以及2通过查询第一个查询的结果获取“最佳”框,以及一个mySql查询,这两个步骤都为我完成了这两个步骤。 /> 现在的问题是它太慢了,我希望此查询运行得更快,我已经研究过优化索引,但这似乎无济于事。我认为也许有更好的方法来构造查询以获得更快的结果集。
SELECT
Listings.PriceCodeDetail.RecNbr AS PCDRecNbr,
(SELECT RecNbr FROM Boxes
WHERE
(
GREATEST(LENGTH, Width, Height) >= GREATEST(atr_grail_live.ip_Spec.ItemLength,atr_grail_live.ip_Spec.ItemWidth,atr_grail_live.ip_Spec.ItemHeight) #GreatestMeasurement
AND LEAST(LENGTH, Width, Height) >= LEAST(atr_grail_live.ip_Spec.ItemLength,atr_grail_live.ip_Spec.ItemWidth,atr_grail_live.ip_Spec.ItemHeight) #LeastMeasurement
AND (LENGTH + Width + Height) - LEAST(LENGTH, Width, Height) - GREATEST(LENGTH, Width, Height) >= (atr_grail_live.ip_Spec.ItemLength+atr_grail_live.ip_Spec.ItemWidth+atr_grail_live.ip_Spec.ItemHeight) - LEAST(atr_grail_live.ip_Spec.ItemLength,atr_grail_live.ip_Spec.ItemWidth,atr_grail_live.ip_Spec.ItemHeight) - GREATEST(atr_grail_live.ip_Spec.ItemLength,atr_grail_live.ip_Spec.ItemWidth,atr_grail_live.ip_Spec.ItemHeight) #MedianMeasurement
)
AND WEIGHT >= (Listings.PriceCodeDetail.QtyBreak * (Listings.ItemListingDetail.ListingQty * atr_grail_live.ip_Spec.ItemWeight)) #TotalWeight
ORDER BY CuIn
LIMIT 1) AS IdealBox # This finds the Longest side, shortest side and middle side and compares it to the Longest, shortest and middle of the item(s) then makes sure the weight is greater that the item(s) weight(s)
FROM
Listings.ItemListingHeader
INNER JOIN Listings.ItemListingDetail ON Listings.ItemListingDetail.HeaderRecNbr = Listings.ItemListingHeader.RecNbr
INNER JOIN Listings.PriceCodeHeader ON Listings.PriceCodeHeader.ListingRecNbr = Listings.ItemListingHeader.RecNbr
INNER JOIN Listings.PriceCodeDetail ON Listings.PriceCodeDetail.HeaderRecNbr = Listings.PriceCodeHeader.RecNbr
INNER JOIN atr_grail_live.ip_Spec ON Listings.ItemListingDetail.IPRecNbr = atr_grail_live.ip_Spec.IP_RecNbr
WHERE
Listings.ItemListingHeader.MarketplaceRecNbr = 1 AND
Listings.PriceCodeHeader.CustomerPriceLevelRecNbr IN (4,5)
AND Listings.ItemListingHeader.RecNbr NOT IN (
SELECT
Listings.ItemListingHeader.RecNbr
FROM
Listings.ItemListingHeader
INNER JOIN Listings.ItemListingDetail ON Listings.ItemListingDetail.HeaderRecNbr = Listings.ItemListingHeader.RecNbr
INNER JOIN Listings.PriceCodeHeader ON Listings.PriceCodeHeader.ListingRecNbr = Listings.ItemListingHeader.RecNbr
INNER JOIN Listings.PriceCodeDetail ON Listings.PriceCodeDetail.HeaderRecNbr = Listings.PriceCodeHeader.RecNbr
INNER JOIN atr_grail_live.ip_Spec ON Listings.ItemListingDetail.IPRecNbr = atr_grail_live.ip_Spec.IP_RecNbr
WHERE
Listings.ItemListingHeader.MarketplaceRecNbr = 1 AND
Listings.PriceCodeHeader.CustomerPriceLevelRecNbr IN (4,5)
AND (atr_grail_live.ip_Spec.ItemLength IS NULL OR atr_grail_live.ip_Spec.ItemLength = '')
GROUP BY Listings.ItemListingHeader.RecNbr
) # This removes from the result set any item(s) that don't have measurements and aren't part of specific groups I have defined, PriceLevel and Marketplace in this instance.
AND atr_grail_live.ip_Spec.IP_RecNbr IN (47467))
# The last AND is only there for now to limit it to one group of items... it will not be used once this is optimized.
我在这里留下了一些评论,以便更好地解释我在做什么。当前,此查询大约需要4秒钟,并返回14行。 如果我删除将其限制为一个项目的最后一行,则将使用超过250K的项目组合...因此将花费很长时间。
请注意,每个子查询本身运行非常快,因此我认为索引正确。
还请注意,如果无法像这样进行优化,则可以更改任何表的结构以适应。我当时以为我可以将Box和Items存储在Length,Width,Height中,并实际上迫使Length最长,Width在中间,Height最短。有帮助吗?
感谢对此的任何指点。
***添加了更多评论**** 如果这有助于我进行最大程度和最少次数的所有数学运算的原因,则是确定最长边,最短边,然后确定中间的那个(中位数)。因此,由于我有3个值L,W,H(长度,宽度,高度),并且可以确定SQL中的最大值和最小值,因此,减去其他两个值后剩下的一个就是中位数。
*添加了表格布局*
CREATE TABLE `ItemListingHeader` (
`RecNbr` int(11) NOT NULL AUTO_INCREMENT,
`SKU` varchar(255) NOT NULL,
`MarketplaceRecNbr` int(11) NOT NULL,
`MarketplaceListingID` varchar(255) NOT NULL,
`MarketplaceShippingTemplateRecNbr` int(11) DEFAULT NULL,
`Status` varchar(1) DEFAULT NULL,
`QtyAvailToReport` int(11) DEFAULT NULL,
`QtyUpdated` datetime DEFAULT NULL,
PRIMARY KEY (`RecNbr`),
UNIQUE KEY `UniqueKey` (`SKU`,`MarketplaceRecNbr`,`MarketplaceListingID`) USING BTREE,
UNIQUE KEY `UniqueKey2` (`SKU`,`MarketplaceRecNbr`) USING BTREE,
KEY `RecNbr` (`RecNbr`)
) ENGINE=InnoDB AUTO_INCREMENT=36351 DEFAULT CHARSET=utf8
CREATE TABLE `ItemListingDetail` (
`RecNbr` int(11) NOT NULL AUTO_INCREMENT,
`HeaderRecNbr` int(11) NOT NULL,
`IPRecNbr` int(11) NOT NULL,
`ListingQty` int(11) DEFAULT NULL,
PRIMARY KEY (`RecNbr`,`HeaderRecNbr`,`IPRecNbr`),
UNIQUE KEY `UniqueKey` (`HeaderRecNbr`,`IPRecNbr`) USING BTREE,
CONSTRAINT `HeaderKey` FOREIGN KEY (`HeaderRecNbr`) REFERENCES `ItemListingHeader` (`RecNbr`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=36344 DEFAULT CHARSET=utf8
CREATE TABLE `PriceCodeHeader` (
`RecNbr` int(11) NOT NULL AUTO_INCREMENT,
`ListingRecNbr` int(11) NOT NULL,
`CustomerPriceLevelRecNbr` int(11) NOT NULL,
`CustomerNbr` int(11) NOT NULL,
PRIMARY KEY (`RecNbr`,`ListingRecNbr`,`CustomerPriceLevelRecNbr`,`CustomerNbr`),
UNIQUE KEY `UniqueKey1` (`ListingRecNbr`,`CustomerPriceLevelRecNbr`) USING BTREE,
KEY `RecNbr` (`RecNbr`),
CONSTRAINT `ListingHeader` FOREIGN KEY (`ListingRecNbr`) REFERENCES `ItemListingHeader` (`RecNbr`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=85976 DEFAULT CHARSET=utf8mb4
CREATE TABLE `PriceCodeDetail` (
`RecNbr` int(11) NOT NULL AUTO_INCREMENT,
`HeaderRecNbr` int(11) NOT NULL,
`PricingMethod` varchar(255) DEFAULT NULL,
`QtyBreak` int(11) NOT NULL,
`Floor` double(11,2) DEFAULT NULL,
`Ceiling` double(11,2) DEFAULT NULL,
`Modifier` double(11,2) DEFAULT NULL,
`Override` double(11,2) DEFAULT NULL,
`AmznMod` double(11,2) DEFAULT NULL,
`PackagingSqFt` double(11,2) DEFAULT NULL,
`LaborMinutes` double(11,2) DEFAULT NULL,
`OtherCosts` double(11,2) DEFAULT NULL,
`FloorMultiplier` double(11,2) DEFAULT NULL,
`CeilingMultiplier` double(11,2) DEFAULT NULL,
`DiscountMultiplier` double(11,2) DEFAULT NULL,
`CurrPrice` double(11,2) DEFAULT NULL,
PRIMARY KEY (`RecNbr`),
UNIQUE KEY `UniqueKey` (`HeaderRecNbr`,`QtyBreak`) USING BTREE,
CONSTRAINT `Header` FOREIGN KEY (`HeaderRecNbr`) REFERENCES `PriceCodeHeader` (`RecNbr`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=242526 DEFAULT CHARSET=utf8mb4
CREATE TABLE `ip_Spec` (
`IP_RecNbr` int(11) NOT NULL DEFAULT '0',
`Amperage` varchar(255) DEFAULT '',
`ANSICode` varchar(255) DEFAULT '',
`Base` varchar(255) DEFAULT '',
`BallastCode` varchar(255) DEFAULT '',
`BeamSpread` varchar(255) DEFAULT '',
`BurnPosition` varchar(255) DEFAULT '',
`Candlepower` varchar(255) DEFAULT '',
`ColorTemp` varchar(255) DEFAULT '',
`ColorTemp_Filter` varchar(255) DEFAULT '',
`Color` varchar(255) DEFAULT '',
`Color_Filter` varchar(255) DEFAULT '',
`CRI` varchar(255) DEFAULT '',
`Diameter` varchar(255) DEFAULT '',
`Diameter_Filter` varchar(255) DEFAULT '',
`DocumentFile1` varchar(255) DEFAULT '',
`DocumentFile2` varchar(255) DEFAULT '',
`DocumentFile3` varchar(255) DEFAULT '',
`DocumentFile4` varchar(255) DEFAULT '',
`DocumentFile5` varchar(255) DEFAULT '',
`DocumentDescription1` varchar(255) DEFAULT '',
`DocumentDescription2` varchar(255) DEFAULT '',
`DocumentDescription3` varchar(255) DEFAULT '',
`DocumentDescription4` varchar(255) DEFAULT '',
`DocumentDescription5` varchar(255) DEFAULT '',
`DocumentType1` varchar(255) DEFAULT '',
`DocumentType2` varchar(255) DEFAULT '',
`DocumentType3` varchar(255) DEFAULT '',
`DocumentType4` varchar(255) DEFAULT '',
`DocumentType5` varchar(255) DEFAULT '',
`Filament` varchar(255) DEFAULT '',
`Finish` varchar(255) DEFAULT '',
`GlassSize` varchar(255) DEFAULT '',
`GlassSize_Filter` varchar(255) DEFAULT '',
`HourLife` varchar(255) DEFAULT '',
`InitialLumens` varchar(255) DEFAULT '',
`ImageFile` varchar(255) DEFAULT '',
`AddtlImage1` varchar(255) DEFAULT '',
`AddtlImage2` varchar(255) DEFAULT '',
`AddtlImage3` varchar(255) DEFAULT '',
`AddtlImage4` varchar(255) DEFAULT '',
`AddtlImage5` varchar(255) DEFAULT '',
`LCL` varchar(255) DEFAULT '',
`Length` varchar(255) DEFAULT '',
`Length_Filter` varchar(255) DEFAULT '',
`Lumens` varchar(255) DEFAULT '',
`Voltage` varchar(255) DEFAULT '',
`Voltage_Filter` varchar(255) DEFAULT '',
`Wattage` varchar(255) DEFAULT '',
`Wattage_Filter` varchar(255) DEFAULT '',
`ShipCode` varchar(255) DEFAULT '',
`SpecStatus` varchar(11) DEFAULT NULL,
`Country_of_Origin` varchar(255) DEFAULT '',
`Contents` varchar(255) DEFAULT '',
`HS_Code` varchar(255) DEFAULT '',
`Dimmable` varchar(1) DEFAULT 'N',
`Enclosure_Rated` varchar(1) DEFAULT 'N',
`Rough_Service` varchar(1) DEFAULT 'N',
`Self_Ballasted` varchar(1) DEFAULT 'N',
`Rapid_Start` varchar(1) DEFAULT 'N',
`Pulse_Start` varchar(1) DEFAULT 'N',
`Covered_Glass` varchar(1) DEFAULT 'N',
`Energy_Star` varchar(1) DEFAULT 'N',
`ROHOS` varchar(1) DEFAULT 'N',
`Description` varchar(255) DEFAULT '',
`BallastType` varchar(255) DEFAULT '',
`BallastStartMethod` varchar(255) DEFAULT '',
`NumberOfLamps` varchar(11) DEFAULT NULL,
`BallastFactor` varchar(11) DEFAULT NULL,
`BallastProductTechnology` varchar(255) DEFAULT NULL,
`MinimumStartTemperature` varchar(11) DEFAULT NULL,
`TotalHarmonicDistortion` varchar(11) DEFAULT NULL,
`EmergencyBallast` varchar(1) DEFAULT 'N',
`CurrentType` varchar(255) DEFAULT '',
`OutputCurrent` varchar(11) DEFAULT NULL,
`OutputCurrentUnitOfMeasure` varchar(255) DEFAULT '',
`OutputVoltage` varchar(11) DEFAULT NULL,
`OutputVoltageUnitOfMeasure` varchar(255) DEFAULT '',
`PowerFactor` varchar(11) DEFAULT NULL,
`Efficiency` varchar(11) DEFAULT NULL,
`Programmable` varchar(1) DEFAULT 'N',
`MinimumWattage` varchar(11) DEFAULT NULL,
`MaximumWattage` varchar(11) DEFAULT NULL,
`HousingMaterial` varchar(255) DEFAULT '',
`LenseMaterial` varchar(255) DEFAULT '',
`MountingStyle` varchar(255) DEFAULT '',
`LightSourceType` varchar(255) DEFAULT '',
`ReflectorType` varchar(255) DEFAULT '',
`IntegratedLightSource` varchar(1) DEFAULT 'N',
`PhotoCellIncluded` varchar(1) DEFAULT 'N',
`SpecsComplete` varchar(1) DEFAULT 'N',
`LocationRating` varchar(255) DEFAULT '',
`ItemLength` varchar(11) DEFAULT NULL,
`ItemLengthUnitOfMeasure` varchar(255) DEFAULT '',
`ItemWidth` varchar(11) DEFAULT NULL,
`ItemWidthUnitOfMeasure` varchar(255) DEFAULT '',
`ItemHeight` varchar(11) DEFAULT NULL,
`ItemHeightUnitOfMeasure` varchar(255) DEFAULT '',
`ItemWeight` varchar(11) DEFAULT NULL,
`ItemWeightUnitOfMeasure` varchar(255) DEFAULT '',
`ProductFamily` varchar(255) DEFAULT '',
`ShortDescription` varchar(255) DEFAULT '',
`LongDescription` text,
`InternalNotes` tinytext,
`BulletPoint1` varchar(255) DEFAULT '',
`BulletPoint2` varchar(255) DEFAULT '',
`BulletPoint3` varchar(255) DEFAULT '',
`BulletPoint4` varchar(255) DEFAULT '',
`BulletPoint5` varchar(255) DEFAULT '',
`WarrantyYears` varchar(11) DEFAULT NULL,
`ETL` varchar(1) DEFAULT 'N',
`CE` varchar(1) DEFAULT 'N',
`UL` varchar(1) DEFAULT 'N',
`DLC` varchar(1) DEFAULT 'N',
`TCLP` varchar(1) DEFAULT 'N',
`IPRated` varchar(1) DEFAULT 'N',
`IPRating` varchar(11) DEFAULT NULL,
`Standby` varchar(1) DEFAULT 'N',
`CeramicMetalHalide` varchar(1) DEFAULT 'N',
`UVProtected` varchar(1) DEFAULT 'N',
`LIFCode` varchar(255) DEFAULT '',
`EnergySaver` varchar(1) DEFAULT 'N',
`ElectricalRequirements` varchar(255) DEFAULT '',
`LumensPerWatt` varchar(11) DEFAULT NULL,
`Disclaimer` text,
`InputElectricalPolarity` varchar(255) DEFAULT '',
`Atmosphere` varchar(255) DEFAULT '',
`BaseMaterial` varchar(255) DEFAULT '',
`GlassMaterial` varchar(255) DEFAULT '',
`DimmablePercentage` varchar(11) DEFAULT NULL,
`ServiceType` varchar(255) DEFAULT '',
`GlassShape` varchar(255) DEFAULT '',
`OutputElectricalPolarity` varchar(255) DEFAULT NULL,
`BeamSpreadDesc` varchar(255) DEFAULT NULL,
`Case1Description` varchar(255) DEFAULT NULL,
`Case1Qty` varchar(255) DEFAULT NULL,
`Case1Length` varchar(255) DEFAULT NULL,
`Case1Width` varchar(255) DEFAULT NULL,
`Case1Height` varchar(255) DEFAULT NULL,
`Case1Weight` varchar(255) DEFAULT NULL,
`Case1GTIN` varchar(255) DEFAULT NULL,
`Case1EAN` varchar(255) DEFAULT NULL,
`Case2Description` varchar(255) DEFAULT NULL,
`Case2Qty` varchar(255) DEFAULT NULL,
`Case2Length` varchar(255) DEFAULT NULL,
`Case2Width` varchar(255) DEFAULT NULL,
`Case2Height` varchar(255) DEFAULT NULL,
`Case2Weight` varchar(255) DEFAULT NULL,
`Case2GTIN` varchar(255) DEFAULT NULL,
`Case2EAN` varchar(255) DEFAULT NULL,
`Case3Description` varchar(255) DEFAULT NULL,
`Case3Qty` varchar(255) DEFAULT NULL,
`Case3Length` varchar(255) DEFAULT NULL,
`Case3Width` varchar(255) DEFAULT NULL,
`Case3Height` varchar(255) DEFAULT NULL,
`Case3Weight` varchar(255) DEFAULT NULL,
`Case3GTIN` varchar(255) DEFAULT NULL,
`Case3EAN` varchar(255) DEFAULT NULL,
`Case4Description` varchar(255) DEFAULT NULL,
`Case4Qty` varchar(255) DEFAULT NULL,
`Case4Length` varchar(255) DEFAULT NULL,
`Case4Width` varchar(255) DEFAULT NULL,
`Case4Height` varchar(255) DEFAULT NULL,
`Case4Weight` varchar(255) DEFAULT NULL,
`Case4GTIN` varchar(255) DEFAULT NULL,
`Case4EAN` varchar(255) DEFAULT NULL,
PRIMARY KEY (`IP_RecNbr`),
UNIQUE KEY `IpRec` (`IP_RecNbr`) USING BTREE,
KEY `SpecStatus` (`SpecStatus`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=ascii
CREATE TABLE `Boxes` (
`RecNbr` int(10) NOT NULL AUTO_INCREMENT,
`Length` int(10) NOT NULL,
`Width` int(10) NOT NULL,
`Height` int(10) NOT NULL,
`Weight` decimal(10,1) NOT NULL,
`CuIn` int(10) NOT NULL,
PRIMARY KEY (`RecNbr`)
) ENGINE=InnoDB AUTO_INCREMENT=184656 DEFAULT CHARSET=utf8mb4
答案 0 :(得分:0)
您的NOT IN
似乎不需要声明。我建议将其替换为
atr_grail_live.ip_Spec.ItemLength IS NOT NULL
AND atr_grail_live.ip_Spec.ItemLength <> ''
在主查询中。
这应该提供相同的结果,但不需要NOT IN
子查询,因为该子查询基本上只是您的主查询的副本。
那之后,我唯一能看到的巨大节省就是
Listings.PriceCodeHeader.CustomerPriceLevelRecNbr IN (4,5)
任何一种IN
或OR
通常都是尝试加快速度的好地方,因为精确匹配往往会更快地处理。
将您的查询分为两个查询,一个查询
Listings.PriceCodeHeader.CustomerPriceLevelRecNbr = 4
和另一个
Listings.PriceCodeHeader.CustomerPriceLevelRecNbr = 5
然后使用UNION ALL
组合查询结果也可能会有所改善。
此后,仅可能丢失某处的索引。提供此优化查询的EXPLAIN
计划,我也许可以帮助确定其他索引在哪里有用。
也就是说,在索引方面,您确实处于游戏的顶端。大多数寻求查询优化帮助的人对索引如何工作没有任何概念,但是您是一个例外。
答案 1 :(得分:0)
WHERE Listings.ItemListingHeader.MarketplaceRecNbr = 1
AND Listings.PriceCodeHeader.CustomerPriceLevelRecNbr IN (4, 5)
AND Listings.ItemListingHeader.RecNbr NOT IN ( SELECT ... )
将NOT IN
更改为LEFT JOIN ... IS NULL
WHERE
子句引用多个表,无法添加跨多个表的索引。无论如何,在MarketplaceRecNbr
上有一个索引。 (稍后再说。)然后在CustomerPriceLevelRecNbr
上。
您的索引效率低下。研究这些规则:
PRIMARY KEY
是UNIQUE
键是INDEX
。 (cf`ItemListingHeader.RecNbr)INDEX
,以避免额外的负担。INDEX(a,b)
,则不需要INDEX(a,b,c)
。您的案例更为复杂,因为它涉及唯一性约束。 UNIQUE(a,b), UNIQUE(a,b,c)
-> UNIQUE(a,b), INDEX(b,a,c)
INDEX(a,b)
可以满足对INDEX(a)
的任何需求,但不能满足INDEX(b)
的需求。那是订购事宜。根据这些规则,为每个表建立一组更好的索引。我会批评它。