简体   繁体   English

SQL查询-大量联接-

[英]SQL Query - Large Number of Joins -

I have a SQL query that I'm using to pull in data from different tables for part details and fitment data. 我有一个SQL查询,用于从不同的表中提取数据以获取零件详细信息和装配数据。 Unfortunately, the way the tables are laid out requires a lot of JOINs it seems. 不幸的是,表的布局方式似乎需要很多JOIN。 I currently have the following query and running it via phpmyadmin just displays a Loading screen, so I imagine it's timing out and wouldn't work in production. 我目前有以下查询,并通过phpmyadmin运行它仅显示一个“正在加载”屏幕,因此我想它超时了,无法在生产环境中工作。

I've added indexes on the tables and columns joined. 我在连接的表和列上添加了索引。 I've optimized the database via phpmyadmin, but I'm still stumped as to how this should or could be done. 我已经通过phpmyadmin优化了数据库,但是我仍然对如何或应该做到这一点感到困惑。 Do I have to split up the queries and combine them with UNION? 我是否必须拆分查询并将其与UNION合并? If so, I'm not even sure how that'd work with this or IF it'd work. 如果是这样,我什至不知道该如何使用此功能,如果可以使用,也无法确定。

Please help. 请帮忙。 :-) :-)

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

The database design is fine. 数据库设计很好。 This is an example of normalization. 这是规范化的示例。 From what I can tell, the tables and columns are well-named. 据我所知,表和列的名称很明确。 I assume the id on each table is a primary key, which would have an index. 我假设每个表上的id是一个主键,它将有一个索引。 The query should be pretty fast, unless there is a large amount of data (relative to available memory). 除非存在大量数据(相对于可用内存),否则查询应该非常快。

Some of your tables are suggesting many-to-many relationships. 您的某些表格暗示了多对多关系。 One possibility is that the query is creating a Cartesian product of rows from different dimensions (within a vehicle) that is multiplying the rows. 一种可能性是查询正在创建不同维度(车辆内)的行的笛卡尔乘积,该乘积将行相乘。 For instance, there might be multiple parts per vehicle and multiple EngineConfig (this is purely a guess as an example), so 100 parts and 20 configs would result in 2,000 rows. 例如,每辆车可能有多个parts ,并且可能有多个EngineConfig (仅作为示例),因此100个零件和20个配置将导致2,000行。

To debug this, start at the top and work down: 要调试此功能,请从顶部开始,然后向下进行操作:

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

Look at the results and be sure that you are getting the rows you expect -- and not any more. 查看结果,并确保获得了期望的 ,并且不再列出。 Then continue adding one join at a time until you spot the issue (either performance or too many rows). 然后,一次继续添加一个联接,直到发现问题(性能或行太多)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM