Php 加快对复杂表的查询速度(约100万行)

Php 加快对复杂表的查询速度(约100万行),php,mysql,sql,query-optimization,page-load-time,Php,Mysql,Sql,Query Optimization,Page Load Time,首先感谢您花时间阅读本文 我正在开发一个处理以下数据的PHPWeb应用程序,到目前为止,在尝试检索数据时,特别是在深入查看选项时,有明显的时间。目前的主要选择是车辆类型、品牌、型号、年份、互联网价格和里程。最终将使用更多的列。此列表中的其他列用于显示整个页面中的数据,因为在一个实例中显示10条记录 表结构: CREATE TABLE `vehicles` ( `id` int(12) NOT NULL AUTO_INCREMENT, `DealerID` int(6) DEFAULT N

首先感谢您花时间阅读本文

我正在开发一个处理以下数据的PHPWeb应用程序,到目前为止,在尝试检索数据时,特别是在深入查看选项时,有明显的时间。目前的主要选择是车辆类型、品牌、型号、年份、互联网价格和里程。最终将使用更多的列。此列表中的其他列用于显示整个页面中的数据,因为在一个实例中显示10条记录

表结构:

CREATE TABLE `vehicles` ( `id` int(12) NOT NULL AUTO_INCREMENT, `DealerID` int(6) DEFAULT NULL, `VIN` varchar(17) DEFAULT NULL, `StockNumber` varchar(10) DEFAULT NULL, `Status` varchar(1) DEFAULT NULL, `VehicleType` int(1) DEFAULT NULL, `Year` int(4) DEFAULT NULL, `Make` varchar(13) DEFAULT NULL, `Model` varchar(24) DEFAULT NULL, `Trim` varchar(35) DEFAULT NULL, `Body` varchar(25) DEFAULT NULL, `VehicleClass` varchar(50) DEFAULT NULL, `VehicleCategory` varchar(6) DEFAULT NULL, `Mileage` int(6) DEFAULT NULL, `Transmission` varchar(24) DEFAULT NULL, `EngineDisplacement` varchar(7) DEFAULT NULL, `EngineSize` varchar(15) DEFAULT NULL, `Induction` varchar(25) DEFAULT NULL, `DriveTrain` varchar(3) DEFAULT NULL, `FuelType` varchar(9) DEFAULT NULL, `FuelEconomyCity` int(2) DEFAULT NULL, `FuelEconomyHighway` int(2) DEFAULT NULL, `FuelEconomyCombined` int(1) DEFAULT NULL, `Doors` int(1) DEFAULT NULL, `OEMColorCodeExterior` varchar(10) DEFAULT NULL, `OEMColorCodeInterior` varchar(10) DEFAULT NULL, `OEMColorNameExterior` varchar(49) DEFAULT NULL, `OEMColorNameInterior` varchar(10) DEFAULT NULL, `GenericColorExterior` varchar(35) DEFAULT NULL, `GenericColorInterior` varchar(38) DEFAULT NULL, `InternetPrice` int(6) DEFAULT NULL, `ComparisonPrice` int(6) DEFAULT NULL, `WholeSalePrice` varchar(10) DEFAULT NULL, `MSRP` varchar(10) DEFAULT NULL, `InternetSpecial` varchar(1) DEFAULT NULL, `OemModelCode` varchar(12) DEFAULT NULL, `HasWarranty` varchar(1) DEFAULT NULL, `CertificationWarranty` int(3) DEFAULT NULL, `WarrantyMonth` int(1) DEFAULT NULL, `WarrantyMiles` int(1) DEFAULT NULL, `CertificationNumber` varchar(7) DEFAULT NULL, `ServiceContract` varchar(1) DEFAULT NULL, `InServiceDate` varchar(19) DEFAULT NULL, `CertificationDate` varchar(19) DEFAULT NULL, `DateManufactured` varchar(19) DEFAULT NULL, `DateCreated` varchar(19) DEFAULT NULL, `DateUpdated` varchar(19) DEFAULT NULL, `DateRemoved` varchar(19) DEFAULT NULL, `DatePhotosUpdated` varchar(19) DEFAULT NULL, `Photos` int(2) DEFAULT NULL, `SuperSizePhotos` int(2) DEFAULT NULL, `AddendumDetails` varchar(10) DEFAULT NULL, `DepartmentComments` varchar(239) DEFAULT NULL, `VehicleComments` varchar(1987) DEFAULT NULL, `Options` varchar(2264) DEFAULT NULL, `PurchasePayment` decimal(5,2) DEFAULT NULL, `PurchaseDownPayment` decimal(6,2) DEFAULT NULL, `PurchaseTerm` int(2) DEFAULT NULL, `PurchaseDisclosure` varchar(10) DEFAULT NULL, `PurchaseRate` decimal(3,2) DEFAULT NULL, `LeasePayment` decimal(2,2) DEFAULT NULL, `LeaseDownPayment` decimal(2,2) DEFAULT NULL, `LeaseTerm` int(1) DEFAULT NULL, `LeaseDisclosure` varchar(10) DEFAULT NULL, `LeaseRate` decimal(2,2) DEFAULT NULL, `LeaseResidual` decimal(2,2) DEFAULT NULL, `Reserved1` varchar(10) DEFAULT NULL, `Reserved2` varchar(10) DEFAULT NULL, `Reserved3` varchar(10) DEFAULT NULL, `Reserved4` varchar(10) DEFAULT NULL, `Reserved5` varchar(10) DEFAULT NULL, `Reserved6` varchar(10) DEFAULT NULL, `sitecert` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `VIN` (`VIN`), KEY `Make` (`Make`), KEY `StockNumber` (`StockNumber`), KEY `Model` (`Model`), KEY `Trim` (`Trim`), KEY `Body` (`Body`), KEY `VehicleClass` (`VehicleClass`), KEY `Transmission` (`Transmission`), KEY `DealerID` (`DealerID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=46527428 ; 有人对优化这个查询或表有什么建议吗?当然,在整个页面中还有其他代码,但我已经将其计时到导致延迟的查询

谢谢你的帮助

更新:

MySQL解释:

id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE vehicles ref Make,Model,DealerID Model 75 const 1675 Using where; Using filesort id选择\u类型表类型可能的\u键\u长度参考行额外 1简单车辆参考品牌、型号、DELERID型号75 const 1675,使用何处;使用文件排序
年份更新为INT

根据您的数据库,您应该在以下字段中添加索引:

Make
VehicleType
Model
InternetPrice
Year
Mileage
DealerId
年份应该是日期类型,而不是文本(INT也有意义)


这会解决你的问题。

我的建议:

  • 按make使用分组
  • 对表进行分区,列可能有用(make,Year)
  • 将表存储在inndb引擎而不是myisam中,并构建 自组织一些聚集索引以加入谓词
对于这种情况,您必须阅读解释结果并相应调整索引

然而,只要对1600行进行排序,我就一点也不麻烦了。如果您仍然想让它更快,那么您似乎需要一个组合键,其中包括一个模型和一个sitecert,然后是价格,两者的顺序正好相反

意味着您必须有两个附加列,其中存储sitecert和price的负值。然后在(Model、nsitecert、nInternetPrice)上建立索引,并在没有DESC的情况下进行排序,以消除文件排序


如果您的搜索查询不涉及任何模型,而是涉及任何参数组合,那么是时候考虑像Sphinx search这样的外部搜索引擎了

您是否查看过?您是否尝试使用
EXPLAIN
查看查询是如何处理的?特别是检查是否进行了完整的表扫描。查询中的解释显示了什么?@AshwinMukhija-我将对此进行研究。此表每晚通过CSV文件截断和更新。您认为通过cron分离数据时会出现问题吗?表有多大?排!你有同样的问题要解决吗?这个方法有帮助吗?我就是这么做的。在文本字段中搜索总是比在数字中搜索更难。这是个坏主意!桌上的货物将永远占去!在创建了这个索引之后,感谢您指出这一点,它应该是一个INT,但我忽略了它。我过去玩过指数游戏,但没有发现令人满意的改进,这让我相信我可以做更多的事情来改进它。指数是一条路要走。当您声明每天晚上都重新加载数据时,只需先删除索引,截断表,加载新数据并重建索引。它不会花费那么长的额外时间,对数据使用(适当的、复合的)索引的结果是,您将在一天中进行更快的查询。PS:我还建议切换到InnoDb;MyIsam只适合玩(IMHO)。这些东西有什么帮助?分组练习运行此查询的配置文件,您将发现!更少的I/O?我被你的回答弄糊涂了!你能用数据库的术语来表达吗?比如他能做什么mysql引擎+DML改进的结构+order+分组依据+less I/OAll我做的是一个我描述的结构索引。你说使用一个不知从何而来的分组依据。我不认为order by是罪魁祸首,而是WHERE。所有这些都添加了一个新字段来避免文件排序,听起来像是techno-make-IMHO。为什么要尝试按正确的顺序扫描1M行(只保留不到2k行),而有一个合适的索引可以更快地找到这些2k行,然后根据需要对它们进行排序。@deroby我就是这么说的。
Make
VehicleType
Model
InternetPrice
Year
Mileage
DealerId