MySQL赢得';如果在ON子句中使用或,则不能在JOIN中使用可用索引

MySQL赢得';如果在ON子句中使用或,则不能在JOIN中使用可用索引,mysql,join,indexing,on-clause,Mysql,Join,Indexing,On Clause,假设您有5个表,每个表都有列: 房屋(身份证、姓名、街道号) 街道(身份证、姓名) 照片(身份证、姓名) 房屋照片(房屋id,照片id) 街道照片(街道id,照片id) 并假设所有“id”列和以“\u id”结尾的列都已具有索引 (事实上,我的问题与房屋或街道无关,只是为了争论。) 现在假设你想把每一条街道分成一列,如果那条街或它的房子有照片,你想把照片放在下一列 这里需要技巧的是所有的房子都在一张桌子上。和其他表格中的所有照片。但是要链接2,我们需要访问所有五个表 我提出了以下查询,其中包

假设您有5个表,每个表都有列:

  • 房屋(身份证、姓名、街道号)
  • 街道(身份证、姓名)
  • 照片(身份证、姓名)
  • 房屋照片(房屋id,照片id)
  • 街道照片(街道id,照片id)
并假设所有“id”列和以“\u id”结尾的列都已具有索引

(事实上,我的问题与房屋或街道无关,只是为了争论。)

现在假设你想把每一条街道分成一列,如果那条街或它的房子有照片,你想把照片放在下一列

这里需要技巧的是所有的房子都在一张桌子上。和其他表格中的所有照片。但是要链接2,我们需要访问所有五个表

我提出了以下查询,其中包含4个连接:

SELECT
    street.name
    ,group_concat(distinct photos.name SEPARATOR '\n') as photos
FROM
    house
    INNER JOIN street ON
        house.street_id = street.id
    LEFT JOIN house_photos ON
        house.id = house_photos.house_id
    LEFT JOIN street_photos ON
        street.id = street_photos.street_id
    LEFT JOIN photos ON
        photos.id = house_photos.photo_id
        OR photos.id = street_photos.photo_id
GROUP BY
    street.name
distinct用于过滤双倍图像,因为当您拥有一栋房子的多张照片以及该房子所在街道的多张照片时,将生成双倍图像。(Carthesian产品)但这与我的问题无关

我遇到的问题是查询速度非常慢。(需要超过1分钟或更长时间才能完成)

当我要求MySQL分析查询('explain extended')时,我发现它在处理最后一个连接(在ON子句中有OR)时不会使用可用的索引

如果我将最后一个连接拆分为两个连接(从而添加第五个连接),查询速度将再次变得非常快(需要一秒钟的时间完成)

我现在的问题是:为什么在ON子句中引入OR,使MySQL不使用该联接的可用索引/键

我已经尝试过使用USE索引和FORCE索引,但它不会改变

欢迎您提供任何解释/帮助。

请说:

最小化WHERE子句中的OR关键字。如果没有索引 这有助于定位或两侧的值,任何行都可以 可能是结果集的一部分,因此必须测试所有行,并且 这需要一个完整的表扫描。如果您有一个索引可以帮助 优化OR查询的一侧,以及有助于 优化另一侧,使用UNION操作符快速运行分离 查询并随后合并结果


不幸的是,这并不能真正回答您的问题,正如您所说,您在所有相关列上都有索引。

事实上,我认为它是。。。我会等着看是否有更合适的答案。但正如你所引用的,我有一个索引,表示OR的1面,1表示OR的另一面。所以根据你的报价,我应该使用联合合并。。。虽然它确实变得凌乱,而且我目前的工作(额外加入)似乎更整洁。
SELECT
    street.name
    ,concat(
        group_concat(distinct photos_from_house.name SEPARATOR '\n')
        ,'\n'
        ,group_concat(distinct photos_from_street.name SEPARATOR '\n')
    ) as photos
FROM
    house
    INNER JOIN street ON
        house.street_id = street.id
    LEFT JOIN house_photos ON
        house.id = house_photos.house_id
    LEFT JOIN street_photos ON
        street.id = street_photos.street_id
    LEFT JOIN photos photos_from_house ON
        photos_from_house.id = house_photos.photo_id
    LEFT JOIN photos photos_from_street ON
        photos_from_street.id = street_photos.photo_id
GROUP BY
    street.name