Mysql 即使所有相关列都已编制索引,添加ORDER BY也会显著降低联接查询的速度。我怎样才能使它更快?

Mysql 即使所有相关列都已编制索引,添加ORDER BY也会显著降低联接查询的速度。我怎样才能使它更快?,mysql,join,sql-order-by,query-optimization,Mysql,Join,Sql Order By,Query Optimization,我有以下联接查询: SELECT table1.*, table2.* FROM Table1 AS table1 LEFT JOIN Table2 AS table2 USING (col1) LEFT JOIN Table3 as table3 USING (col1) WHERE 3963.191 * ACOS( (SIN(PI() * $usersLatitude / 180) * S

我有以下联接查询:

SELECT
    table1.*, 
    table2.*
FROM 
    Table1 AS table1 
LEFT JOIN 
    Table2 AS table2 
USING 
    (col1)
LEFT JOIN 
    Table3 as table3 
USING 
    (col1) 
WHERE 
    3963.191 * 
    ACOS(
    (SIN(PI() * $usersLatitude / 180) * SIN(PI() * table3.latitude / 180)) 
    +
    (COS(PI() * $usersLatitude / 180) * COS(PI() * table3.latitude / 180) * COS(PI() * table3.longitude / 180 - PI() * 37.1092162 / 180))
    ) <= 10 
AND 
    table1.col1 != '1' 
AND 
    table1.col2 LIKE 'A' 
AND 
    (table1.col3 LIKE 'X' OR table1.col3 LIKE 'X-Y') 
AND 
    (table2.col4 = 'Y' OR table2.col5 = 'Y') 
它在3秒内执行

查询中的所有列都被索引,包括
表1.col6
中使用的
ORDER BY

我试过了,但没有成功

如何使用
ORDER BY
快速运行此查询


编辑:

不按
顺序解释扩展的
结果:

id  select_type table   type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  table1  ALL PRIMARY,col2,col3   NULL    NULL    NULL    140101  72.61   Using where
1   SIMPLE  table2  eq_ref  PRIMARY,col4,col5   PRIMARY 4   table1.col1 1   100 Using where
1   SIMPLE  table3  eq_ref  PRIMARY PRIMARY 4   table1.col1 1   100 Using where
id  select_type table   type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  table1  ALL PRIMARY,col2,col3   NULL    NULL    NULL    140101  72.61   Using where; Using filesort
1   SIMPLE  table2  eq_ref  PRIMARY,col4,col5   PRIMARY 4   table1.col1 1   100 Using where
1   SIMPLE  table3  eq_ref  PRIMARY PRIMARY 4   table1.col1 1   100 Using where
使用
顺序解释扩展的的结果:

id  select_type table   type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  table1  ALL PRIMARY,col2,col3   NULL    NULL    NULL    140101  72.61   Using where
1   SIMPLE  table2  eq_ref  PRIMARY,col4,col5   PRIMARY 4   table1.col1 1   100 Using where
1   SIMPLE  table3  eq_ref  PRIMARY PRIMARY 4   table1.col1 1   100 Using where
id  select_type table   type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  table1  ALL PRIMARY,col2,col3   NULL    NULL    NULL    140101  72.61   Using where; Using filesort
1   SIMPLE  table2  eq_ref  PRIMARY,col4,col5   PRIMARY 4   table1.col1 1   100 Using where
1   SIMPLE  table3  eq_ref  PRIMARY PRIMARY 4   table1.col1 1   100 Using where

编辑2:

查询中所有列的数据类型(根据要求):


所有3个表(表1、表2和表3)都是
MyISAM

这不是一个解决方案,但可能会有所帮助:避免使用“*”指定所需的列,并显式指定它们。当您使用*来指定所有列时,MySQL在对数据进行排序时,需要做更多的工作来分流数据,因此更有可能进行文件排序,这很慢

此外,索引对MySQL排序数据的容易程度几乎没有影响,尽管您应该检查它是否使用了BTREE索引,因为它们更有可能保持相对良好的排序


最糟糕的是,如果您还没有阅读MySQL手册,您可能需要阅读一下手册中的内容。我看不到任何适用的内容,但您可能会看到我缺少的内容。

我唯一可以考虑的解决方法是将表更改为默认的order by,然后将查询中的
order by一起删除


如果您的查询速度与您指示的一样快,我希望它返回的数据集相当小。如果是这样的话,我会按原样包装你的,然后把订单放在外面,比如

select
      PreQuery.*
   from
      ( Your Entire Query Without the order by clause ) as PreQuery
   order by
      PreQuery.Col6 Desc
这样,外部查询与现有索引无关,只返回数据。。。然后,该结果将按照原始结果应用顺序


希望这能为您解决问题。

除了我的另一个答案外,我还提供了一个选择,将您现有的查询包装在一个选择中,然后对结果排序。这里是查询的另一个选项。。。如果我的解释不正确,请纠正我

您正在对表2进行左连接,但需要Col4或Col5='Y',因此由于where子句,指示内部连接(记录必须存在于表1和表2上)


同样地,在表3中加入了表1,但限制了距离为什么要对非通配符值执行
类似的操作?这将使规划者更加悲观。但最重要的是,您需要查看查询计划器显示的内容


另外,您最近是否对表格进行了
分析
?如果行统计信息关闭,计划员将做出错误的选择。

您看过执行计划了吗?可能是您指定的索引没有覆盖查询或未被使用。我怀疑“喜欢”的操作员可能与此有关it@Charleh:我如何看待执行计划?如果为查询中使用的每一列指定了索引,那么我指定的索引如何不覆盖查询或不被使用?提前感谢您提供的更多信息。请查看MySql文档页面。试试看,看看是否使用了索引,这是唯一可以确定的方法!另请看-一个很好的信息是:
通过获取EXPLAIN输出的rows列中的值的乘积,您可以很好地指示连接有多好。这应该大致告诉您MySQL执行查询必须检查多少行。如果使用max_join_size系统变量限制查询,则此行乘积还用于确定要执行的多个table SELECT语句以及要中止的语句。请参阅第8.11.2节“调整服务器参数”。
因此,请尝试使用或不使用“排序依据”,并检查results@Charleh:好的,现在进行解释,包括和不包括命令,并将在稍后发布结果。谢谢。我同意你说的,但在这种情况下没什么区别。例如,我没有选择表1.*,而是选择表2.*
我只是尝试了
selecttable1.col1
,但仍然花了3秒钟。如果你还有其他想法,请告诉我。谢谢不,我累坏了。我将编辑答案以提及MySQL手册中关于优化
orderby
的页面,但我看到其中有很多可能会有所帮助。谢谢。对不起,我帮不上忙了。你提出的解决方案和这个解决方案不一样吗?如果是这样,那么正如我在主要帖子中提到的,该解决方案并没有提高查询速度。还有其他想法吗?那是我希望避免的最后手段。你知道为什么简单地添加ORDER BY会使查询的长度增加10倍以上吗?因为默认的顺序是按主键,而在另一列上对其重新排序需要filesort,这在本质上是相当慢的。在上面添加DESC命令会进一步降低速度。简单地说,MySQL有很多工作要做,因为这一切。奇怪的是,我在我的网站上的其他几个地方使用ORDER BY DESC,但它并没有像这个查询那样让它慢下来。这个查询有一个特定的原因,它会随着ORDERBY的出现而显著减慢。这是我希望在这里解开的一个谜非常有趣,谢谢!我将对此进行一次尝试并报告。排序结果的
ORDER BY
在哪里?@程序员,我只需在没有Where的情况下进行一次快速测试,看看它与您的原始结果(没有ORDER BY)相比如何,然后,像往常一样在Where子句后添加ORDER BY。好的,我尝试了,没有您建议的索引,而且速度也没有提高。你能给我看看你的SQL代码吗
SELECT STRAIGHT_JOIN
      T1.*, 
      T2.*
   FROM 
      Table1 AS T1
         JOIN Table2 AS T2
            ON T1.Col1 = T2.Col1
            AND ( T2.Col4 = 'Y' OR T2.Col5 = 'Y' )
         JOIN Table3 as T3
            ON T1.Col1 = T3.Col1
            AND 3963.191 
               * ACOS(  (SIN(PI() * $usersLatitude / 180) * SIN(PI() * T3.latitude / 180)) 
                                + (  COS(PI() * $usersLatitude / 180) * COS(PI() * T3.latitude / 180) 
                                   * COS(PI() * table3.longitude / 180 - PI() * 37.1092162 / 180)
                        )   
                     ) <= 10 
   WHERE
          T1.Col2 LIKE 'A'
      AND ( T1.col3 LIKE 'X' OR T1.col3 LIKE 'X-Y') 
      AND T1.Col1 != '1'
   ORDER BY
      T1.Col6
On Table 1, I would have an index on ( Col2, Col3, Col1, Col6 )
On Table 2 on ( Col1, Col4, Col5 )
On Table 3 on ( Col1 )   <-- assume already had this.