【发布时间】:2019-04-09 18:55:39
【问题描述】:
我有几个表连接在一起,目的是确定“最佳”,即最小的盒子,单个项目或一组这些项目将适合。 只是为了让我“足够接近”,这样我就可以确定不同承运人的该物品或物品的运输成本。
我结合了两个步骤: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.
我在那里留下了一些 cmets,以便更好地解释我在做什么。目前,此查询大约需要 4 秒并返回 14 行。 如果我删除将其限制为一个项目的最后一行,它将使用超过 250K 的项目组合......所以会花费很长时间。
请注意,每个子查询本身运行得非常快,所以我认为我的索引是正确的。
还要注意,如果不能像这样优化,我可以更改任何表的结构以适应。我在想我可以将盒子和物品存储在长度、宽度、高度中,实际上强制长度为最长,宽度在中间,高度为最短边。那会有帮助吗?
感谢您对此的任何指示。
*** 添加了更多的 cmets **** 如果它有助于我用最大和最小的方式进行所有数学运算的原因是确定最长边,最短边,然后是中间的那个(中位数)。因此,由于我有 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
【问题讨论】:
-
请为查询中的所有表提供
SHOW CREATE TABLE tablename输出。 -
好主意!谢谢...我添加了它们。
-
好的,让我们弄清楚应该把注意力集中在哪里。尝试在您的选择中删除子查询,然后重新运行查询(至少两次,只报告最后一个结果。)执行需要多长时间?如果很快,那么我们知道子查询是主要问题。如果没有变化,那么我们知道 SELECT 中的子查询与速度无关。如果只是一些改进,那么我们需要修复它和主查询。
-
打破它...明白了... 好的,如果我在选择中删除子查询,查询将在 0.626 秒内运行,不到一秒即可返回 14 行。如果我使用主查询中的一条记录自行运行子查询,则需要 0.226 秒……超级快。那么也许没有子查询的 .795 的初始查询实际上是需要优化的?
-
好的,这很有帮助!我采用子查询部分并在 Boxes 表上为长度、宽度、高度、重量、CuIn 的每个单独字段建立索引,子查询现在下降到 0.001 秒......所以我再次运行我的主查询,它我的 14 行现在下降到大约一秒钟!现在我需要继续前进,让它变得更好,因为如果我能做得更快,1 秒 x 250K 仍然太长。优秀的!这很有趣!