相关疑难解决方法(0)

索引是否必须覆盖所有选定的列才能用于 ORDER BY?

在 SO,最近有人问为什么 ORDER BY 不使用索引?

这种情况涉及 MySQL 中的一个简单的 InnoDB 表,包括三列和 10k 行。其中一列,一个整数,被索引——OP 试图检索他在该列上排序的整个表:

SELECT * FROM person ORDER BY age
Run Code Online (Sandbox Code Playgroud)

他附上了EXPLAIN输出,显示这个查询是用 a filesort(而不是索引)解决的,并询问为什么会这样。

尽管提示 FORCE INDEX FOR ORDER BY (age) 导致使用索引,但有人回答(通过其他人的支持评论/赞成)索引仅用于在所选列都从索引中读取时进行排序(即通常Using indexExtra列中指示的EXPLAIN输出)。后来给出了一个解释,遍历索引然后从表中获取列会导致随机 I/O,MySQL 认为这比filesort.

这似乎与关于ORDER BY优化的手册章节背道而驰,它不仅传达了强烈的印象,即满足ORDER BY索引比执行额外排序更可取(实际上,filesort是快速排序和归并排序的组合,因此 必须有一个下限; 虽然按顺序遍历索引并寻找表应该是 - 所以这是完全有道理的),但它也忽略了这种所谓的“优化”,同时还说明了:Ω(nlog n)O(n)

以下查询使用索引来解析ORDER …

mysql innodb index order-by

16
推荐指数
2
解决办法
5816
查看次数

由于简单地删除一个额外的约束,较少限制的查询返回较少的结果

看看这个查询

SELECT DISTINCT
  TB.ID,
  TB.Latitude,
  TB.Longitude,
  111151.29341326*SQRT(pow(-6.185-TB.Latitude,2)+pow(106.773-TB.Longitude,2)*0.98839228980165) AS Distance
FROM
  `tablebusiness` AS TB
   join tableauxiliary as TA on TA.BusinessID=TB.ID
WHERE
MBRContains(
   GeomFromText ('MULTIPOINT(-6.2317830813328 106.72621691867,-6.1382169186672  106.81978308133)'),
   TA.Latlong
   )
   AND
MATCH (FullTextSearch) AGAINST ('kucing*' IN BOOLEAN MODE)
ORDER BY
  Distance
LIMIT
  0, 20
Run Code Online (Sandbox Code Playgroud)

这基本上是搜索 TA.LatLong 在 'MULTIPOINT(-6.2317830813328 106.72621691867,-6.1382169186672 106.81978308133)' 框中的所有 biz,并且在该框之后必须包含 ku

这将返回 22 行。

现在将其与此查询进行比较

SELECT DISTINCT
  TB.ID,
  TB.Latitude,
  TB.Longitude,
  111151.29341326*SQRT(pow(-6.185-TB.Latitude,2)+pow(106.773-TB.Longitude,2)*0.98839228980165) AS Distance
FROM
  `tablebusiness` AS TB
   join tableauxiliary as TA on TA.BusinessID=TB.ID
WHERE
MBRContains(
   GeomFromText ('MULTIPOINT(-6.2317830813328 106.72621691867,-6.1382169186672  106.81978308133)'),
   TA.Latlong
   ) …
Run Code Online (Sandbox Code Playgroud)

mysql mysql-5.5 spatial

6
推荐指数
1
解决办法
622
查看次数

有没有办法向 MySQL 的查询优化器提示应该首先完成哪些约束?

这是我当前的查询:

SELECT BusinessID as ID,  
  111151.29341326*SQRT(pow(-6.186751-X(LatLong),2)+pow(106.772835-Y(LatLong),2)*0.98838574205337) AS Distance from
(
    SELECT *
    FROM
      tableauxiliary
    WHERE
      MBRContains(
    GeomFromText (
        'MULTIPOINT(-6.1934985598076 106.76604791159,-6.1800034401924 106.77962208841)'
        ),
        Latlong)=1  
    AND Prominent >15 
) AS TA

    Having Distance <= 18238
    ORDER BY
  Distance
LIMIT
  0, 45
Run Code Online (Sandbox Code Playgroud)

请注意,他们我使用了子查询。它使用子查询的原因是因为我想要

      MBRContains(
    GeomFromText (
        'MULTIPOINT(-6.1934985598076 106.76604791159,-6.1800034401924 106.77962208841)'
        ),
        Latlong)=1   
Run Code Online (Sandbox Code Playgroud)

首先要完成。这将查询时间从 19 秒减少到 0.9 秒。

有没有办法提示mysql查询优化器,这样我就不需要使用子查询

更新:

我试过:

SELECT BusinessID as ID,  
  111151.29341326*SQRT(pow(-6.186751-X(LatLong),2)+pow(106.772835-Y(LatLong),2)*0.98838574205337) AS Distance from tableauxiliary 
USE Index (LatLong_2,FullTextSearch)
WHERE
    MBRContains(
    GeomFromText (
        'MULTIPOINT(-6.1934985598076 106.76604791159,-6.1800034401924 106.77962208841)'
        ),
        Latlong)  
    AND Prominent >15 …
Run Code Online (Sandbox Code Playgroud)

mysql optimization subquery

6
推荐指数
2
解决办法
1990
查看次数

Mysql全文搜索my.cnf优化

我在https://serverfault.com/questions/353888/mysql-full-text-search-cause-high-usage-cpu 上提出了一个问题一些用户建议在这里提问。

我们建立了一个新闻网站。每天我们都会从web api输入数以万计的数据。

为了提供精准的搜索服务,我们的表使用了MyISAM,建立了全文索引(标题、内容、日期)。我们的网站正在测试 Godaddy VDS,内存为 2GB,空间为 30GB(无交换,因为 VDS 不允许构建交换)。CPU是Intel(R) Xeon(R) CPU L5609 @ 1.87GHz

运行一个 ./mysqltuner.pl

我们得到一些结果:

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.5.20
[OK] Operating on 32-bit architecture with less than 2GB RAM

-------- Storage Engine Statistics -------------------------------------------
[--] Status: -Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
[--] Data in MyISAM tables: 396M (Tables: 39)
[--] Data in InnoDB tables: 208K (Tables: 8)
[!!] …
Run Code Online (Sandbox Code Playgroud)

mysql myisam full-text-search my.cnf

5
推荐指数
1
解决办法
9780
查看次数

全文和左连接的慢查询

我有3张桌子

  • 约 250,000 条记录。
  • table1 是 MyISAM,添加带有标题和内容的 fullindex,添加带有 pid 的索引。
  • table2 和 table3 是 InnoDB,用 pid 添加索引。

只查询table3,只需要0.04秒。

select * from table3 
WHERE MATCH (title,content)
AGAINST ('+words' IN BOOLEAN MODE)
ORDER BY pid
Run Code Online (Sandbox Code Playgroud)

但是像这样查询,花费 16.87 秒。

SELECT * 
FROM table1
INNER JOIN table2 ON table1.pid = table2.pid
LEFT JOIN table3 ON table1.pid = table3.pid
WHERE MATCH (table3.title, table3.content)
AGAINST ('+words' IN BOOLEAN MODE)
ORDER BY table3.pid
Run Code Online (Sandbox Code Playgroud)

我为第二个查询制定了一个解释计划,返回:

id select_type  table     type  possible_keys    key    key_len    ref               rows      Extra
1  SIMPLE       table1 …
Run Code Online (Sandbox Code Playgroud)

mysql full-text-search select

5
推荐指数
1
解决办法
7745
查看次数