2013-07-22 78 views
0

我有一個SQL查詢,我用來從不同的表中獲取部分詳細信息和配件數據的數據。不幸的是,表格的佈局方式似乎需要大量的JOIN。我目前有以下查詢,並通過phpmyadmin運行它只顯示一個加載屏幕,所以我想它是超時,並不會在生產中。SQL查詢 - 大量的聯接 -

我在連接的表和列上添加了索引。我已經通過phpmyadmin優化了數據庫,但我仍然難以理解應該如何完成這個任務。我是否必須拆分查詢並將它們與UNION結合?如果是這樣,我甚至不知道這是如何工作,如果它會工作。

請幫忙。 :-)

EXPLAIN SELECT Import_Values.base_vehicle_id, 
    Import_Values.qty, 
    Import_Values.part_type_id, 
    Import_Values.part_id, 
    Import_Values.position_id, 
    Import_Values.note, 
    Parts.partterminologyname, 
    BaseVehicle.YearID, 
    Make.MakeName, 
    Model.modelname, 
    SubModel.SubModelName, 
    EngineDesignation.EngineDesignationName, 
    EngineVIN.EngineVINName, 
    EngineBase.Liter, 
    EngineBase.CC, 
    EngineBase.CID, 
    EngineBase.Cylinders, 
    EngineBase.BlockType, 
    EngineBase.EngBoreIn, 
    EngineBase.EngBoreMetric, 
    EngineBase.EngStrokeIn, 
    EngineBase.EngStrokeMetric, 
    FuelDeliveryType.FuelDeliveryTypeName, 
    FuelDeliverySubType.FuelDeliverySubTypeName, 
    FuelSystemControlType.FuelSystemControlTypeName, 
    FuelSystemDesign.FuelSystemDesignName, 
    Aspiration.AspirationName, 
    CylinderHeadType.CylinderHeadTypeName, 
    FuelType.FuelTypeName, 
    IgnitionSystemType.IgnitionSystemTypeName, 
    Mfr.MfrName, 
    EngineVersion.EngineVersion, 
    Valves.ValvesPerEngine, 
    BedLength.BedLength, 
    BedLength.BedLengthMetric, 
    BedType.BedTypeName 
    FROM 
    Import_Values 
    INNER JOIN BaseVehicle 
     ON Import_Values.base_vehicle_id=BaseVehicle.BaseVehicleID 
    INNER JOIN Parts 
     ON Import_Values.part_type_id=Parts.PartTerminologyID 
    INNER JOIN Make 
     ON BaseVehicle.MakeID=Make.MakeID 
    INNER JOIN Model 
     ON BaseVehicle.ModelID=Model.ModelID 
    INNER JOIN Vehicle 
     ON Import_Values.base_vehicle_id=Vehicle.BaseVehicleID 
    INNER JOIN SubModel 
     ON Vehicle.SubModelID=SubModel.SubModelID 
    INNER JOIN VehicleToEngineConfig 
     ON Vehicle.VehicleID=VehicleToEngineConfig.VehicleID 
    INNER JOIN EngineConfig 
     ON VehicleToEngineConfig.EngineConfigID=EngineConfig.EngineConfigID 
    INNER JOIN EngineDesignation 
     ON EngineConfig.EngineDesignationID=EngineDesignation.EngineDesignationID 
    INNER JOIN EngineVIN 
     ON EngineConfig.EngineVINID=EngineVIN.EngineVINID 
    INNER JOIN EngineBase 
     ON EngineConfig.EngineBaseID=EngineBase.EngineBaseID 
    INNER JOIN FuelDeliveryConfig 
     ON EngineConfig.FuelDeliveryConfigID=FuelDeliveryConfig.FuelDeliveryConfigID 
    INNER JOIN FuelDeliveryType 
     ON FuelDeliveryConfig.FuelDeliveryTypeID=FuelDeliveryType.FuelDeliveryTypeID 
    INNER JOIN FuelDeliverySubType 
     ON FuelDeliveryConfig.FuelDeliverySubTypeID=FuelDeliverySubType.FuelDeliverySubTypeID 
    INNER JOIN FuelSystemControlType 
     ON FuelDeliveryConfig.FuelSystemControlTypeID=FuelSystemControlType.FuelSystemControlTypeID 
    INNER JOIN FuelSystemDesign 
     ON FuelDeliveryConfig.FuelSystemDesignID=FuelSystemDesign.FuelSystemDesignID 
    INNER JOIN Aspiration 
     ON EngineConfig.AspirationID=Aspiration.AspirationID 
    INNER JOIN CylinderHeadType 
     ON EngineConfig.CylinderHeadTypeID=CylinderHeadType.CylinderHeadTypeID 
    INNER JOIN FuelType 
     ON EngineConfig.FuelTypeID=FuelType.FuelTypeID 
    INNER JOIN IgnitionSystemType 
     ON EngineConfig.IgnitionSystemTypeID=IgnitionSystemType.IgnitionSystemTypeID 
    INNER JOIN Mfr 
     ON EngineConfig.EngineMfrID=Mfr.MfrID 
    INNER JOIN EngineVersion 
     ON EngineConfig.EngineVersionID=EngineVersion.EngineVersionID 
    INNER JOIN Valves 
     ON EngineConfig.ValvesID=Valves.Valvesid 
    INNER JOIN VehicleToBedConfig 
     ON Vehicle.VehicleID=VehicleToBedConfig.VehicleID 
    INNER JOIN BedConfig 
     ON VehicleToBedConfig.BedConfigID=BedConfig.BedConfigID 
    INNER JOIN BedLength 
     ON BedConfig.BedLengthID=BedLength.BedLengthID 
    INNER JOIN BedType 
     ON BedConfig.BedTypeID=BedType.BedTypeID 
+0

不好的數據庫設計!你真的需要1個查詢中的所有數據嗎? – Sergio

+0

嘿塞爾吉奧。這真的很糟糕。不幸的是,這是第三方提供的處理汽車零部件配件數據的標準設計。 –

+3

那麼,每個表可以存儲數千條記錄,所以你需要在1個查詢中記錄所有這些記錄,或者你可以只需要拉一些過濾器,所以最終查詢至少會有'where'子句? – Sergio

回答

4

數據庫設計沒問題。這是正常化的一個例子。從我所知道的來看,這些表格和專欄都很有名。我假設每個表上的id是一個主鍵,它將有一個索引。查詢應該非常快,除非有大量數據(相對於可用內存)。

一些表格提示了多對多的關係。一種可能性是查詢創建了行數相乘的不同維度(車輛內)的行的笛卡爾乘積。例如,每輛車可能有多個parts和多個EngineConfig(這純粹是一個猜測),因此100個零件和20個配置會導致2,000行。

要調試這一點,在頂部開始往下工作:

select * 
FROM Import_Values INNER JOIN 
    BaseVehicle 
    ON Import_Values.base_vehicle_id=BaseVehicle.BaseVehicleID 

看結果,並確保你所得到的你期望 - 而不是更多。然後繼續添加一個連接,直到您發現問題(性能或行數過多)。

+0

'EXPLAIN'可以向您顯示哪些JOIN正在爲大量的行做出貢獻。在解釋結果中查找類型不同於'eq_ref'的行以及它們的行數。 – Vatev