MySQL查询优化:正确的索引

MySQL查询优化:正确的索引,mysql,sql,optimization,indexing,Mysql,Sql,Optimization,Indexing,我需要帮助在SQL查询中使用一个左连接选择正确的索引 我有两个表(对象和月度报告): 创建一些表对象( id int(11)非空自动增量, ..., 主键(id), ); 创建表月份报告( id int(11)非空自动增量, 某些对象id int(11)默认为空, 月份int(11)不为空, 年份int(11)不为空, ..., 主键(id), 指数IDX_123(月、年), 索引IDX_456(某些对象id), 索引IDX_789(某些对象id、月份、年份), 约束FK_123外键(某些对象i

我需要帮助在SQL查询中使用一个
左连接选择正确的索引

我有两个表(对象和月度报告):

创建一些表对象(
id int(11)非空自动增量,
...,
主键(id),
);
创建表月份报告(
id int(11)非空自动增量,
某些对象id int(11)默认为空,
月份int(11)不为空,
年份int(11)不为空,
...,
主键(id),
指数IDX_123(月、年),
索引IDX_456(某些对象id),
索引IDX_789(某些对象id、月份、年份),
约束FK_123外键(某些对象id)
在更新限制时删除限制时引用某些_对象(id)
)
我需要选择在特定月份有报告或没有报告的所有对象。我尝试了以下查询:

从一些对象中选择*,以便
LEFT JOIN month_报告mr.some_object_id=so.id上的mr
哪里
先生月份=:月份
年先生=:年
或者mr.id为空
解释
结果:

id选择类型表类型可能的键
1.这么简单
1个简单mr所有IDX_456,IDX_789
解释
没有
的结果或mr.id为空

id选择类型表类型可能的键键参考
1个简单mr参考IDX_123,IDX_456,IDX_789 IDX_123常数,常数
1个简单的so eq_ref初级
但是如果没有
或mr.id为空
我就不会得到没有报告的对象

我应该添加哪些其他索引?我需要更改查询吗

对我的英语很抱歉

UPD。
分析表
返回“状态正常”<代码>使用
力索引解释结果(10个对象,只有一个有报告):

id选择类型表类型可能的键键行
1简单,所以全部10
1简单mr参考IDX_789 IDX_789 1

嗯,我没有得到我需要的东西。我将考虑如何用另一种方式解决我的问题

不幸的是,我不能在我的框架中使用
FORCE INDEX
。但我需要获取所有对象,即使它们都没有报告


我只是想优化我的SQL查询。在单个查询中执行此操作是一次失败的尝试:)

嗯,我没有得到我需要的。我将考虑如何用另一种方式解决我的问题

不幸的是,我不能在我的框架中使用
FORCE INDEX
。但我需要获取所有对象,即使它们都没有报告


我只是想优化我的SQL查询。在单个查询中执行此操作是一种不成功的尝试:)

以下是一种可能满足您需要的重新格式:

SELECT  so.*
    FROM  some_objects so
    LEFT JOIN  month_reports mr
          ON mr.some_object_id = so.id
          AND ( mr.month = :month  AND  mr.year = :year )
注意,由于
LEFT
的工作方式,它避免处理
为NULL的问题。但是,通过将
WHERE
移动到
ON
上,它稍微改变了语义

以下使用
UNION
而不是
的重新编译也可能有效(假设框架允许您这样做):


下面是一个可能满足您要求的重新表述:

SELECT  so.*
    FROM  some_objects so
    LEFT JOIN  month_reports mr
          ON mr.some_object_id = so.id
          AND ( mr.month = :month  AND  mr.year = :year )
注意,由于
LEFT
的工作方式,它避免处理
为NULL的问题。但是,通过将
WHERE
移动到
ON
上,它稍微改变了语义

以下使用
UNION
而不是
的重新编译也可能有效(假设框架允许您这样做):


您可以向现有的
IDX\u 123
@Vatev添加
some\u object\u id
,对不起,我修复了IDX\u 789。它有一些\u object\u id、month、year列,MySQL服务器不使用它:(当行太少时,它有时会这样做(如果行太少,则添加一些)。尝试运行。如果不起作用,则添加
FORCE KEY(IDX\u 789)
加入并发布查询计划。同时发布行数估计值。@Vatev我将更新添加到问题中。结果正常吗?看起来正常。第一个查询计划的行估计值是多少(
SIMPLE mr ALL
)?您可以向现有的
IDX\U 123
@Vatev添加
some\u object\u id
。@Vatev抱歉,我修复了IDX\u 789。它有一些\u object\u id、month、year列,MySQL服务器不使用它:(当行太少时,有时会这样做(如果行太少,则添加一些)。尝试运行。如果不起作用,请添加
FORCE KEY(IDX\u 789)
加入并发布查询计划。同时发布行数估计值。@Vatev我将更新添加到问题中。结果正常吗?看起来正常。第一个查询计划(
SIMPLE mr ALL
)的行估计值是多少?