查询性能的最佳实践是什么?

时间:2018-04-19 22:52:44

标签: php mysql sql performance query-performance

在这个Table上我使用这个脚本:

$SQL = "
SELECT id, col
FROM t
ORDER BY CASE WHEN 'A B C D E' LIKE CONCAT(col, '%') THEN col END DESC;
";
$stmt = $connect->prepare($SQL);
$stmt->execute();
if ($stmt->rowCount > 0) {
    .    .  PULL_DATA  .    .
} else {
    echo 'No Data Pulled';
}

我使用了ORDER BY,因为我想首先提取重要数据,这与col = A B C D E相关,然后A B C D那么A B C那么A B然后A

但是如果这些col =值都不存在,那么要提取与这组字符串无关的数据,那么如果id为1, 2, 7, 5的col,我仍然会得到要使用的其他记录,现在这个查询似乎根本无法进行优化,所以我想到了Query上使用WHERE代替ORDER BY的以下脚本: / p>

$SQL = "
SELECT id, col
FROM t
WHERE 'A B C D E' LIKE CONCAT(col, '%')
ORDER BY col DESC;
";
$stmt = $connect->prepare($SQL);
$stmt->execute();
if ($stmt->rowCount > 0) {
    .    .  PULL_DATA  .    .
} else {
    $SQL = "
    SELECT id, col
    FROM t
    ORDER BY col DESC;
    ";
    $stmt = $connect->prepare($SQL);
    $stmt->execute();
    if ($stmt->rowCount > 0) {
        .    .  PULL_DATA  .    .
    } else {
        echo 'No Data Pulled';
    }
}

这是保持性能的好方法还是有更好的方法?

为防止混淆,A B C D E不是静态字符串,而是变量

总是字母,

可以是Hello My World之类的字词,其中查询按Hello My World排序值,然后Hello My然后Hello此查询基于此Question <构建/ p>

1 个答案:

答案 0 :(得分:0)

First Query

Well, the query:

SELECT id, col
  FROM t
  ORDER BY CASE WHEN 'A B C D E' LIKE CONCAT(col, '%') THEN col END DESC;

selects all the rows of the table. There's no optimization you can use here, since the order by expression changes per query. No index can be created that will help on any order.

Second Query

The second query can be optimized. If you know that col has a minimum length then it can be optimized, even if it's 1 character long (hopefully longer).

For this example, let's assume col has a minimum length of three characters. Then I would create an index for those three head characters as:

alter table t add (col_head as substring(col, 1, 3));

create index ix1_t on t (col_head);

Then add an extra condition, that seems redundant. This extra condition will try to use an Index Range Scan table access mode that is much faster than a Full Table Scan:

SELECT id, col
  FROM t
  where col_head = substring('A B C D E', 1, 3) 
    and 'A B C D E' LIKE CONCAT(col, '%')
  ORDER BY col DESC;

Note 1: the parameter 'A B C D E' is added twice in the SQL.

Note 2: before and after the change, retrieve the execution plan MySQL is using, and see if there are any differences. To retrieve the execution plan run:

explain <my_query>