哪个索引或查询将具有最佳性能?

时间:2019-06-30 04:45:19

标签: mysql indexing

我的表有60万行:

CREATE TABLE `vector` (
  `word_id` int(11) NOT NULL,
  `а` tinyint(1) NOT NULL DEFAULT '0',
    [........]
  `ю` tinyint(1) NOT NULL DEFAULT '0',
  `я` tinyint(1) NOT NULL DEFAULT '0',
  `total` int(8) AS (а+б+в+г+д+e+ё+ж+з+и+й+к+л+м+н+о+п+
                     р+с+т+у+ф+х+ц+ч+ш+щ+ъ+ь+ы+э+ю+я) PERSISTENT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


ALTER TABLE `vector`
  ADD PRIMARY KEY (`word_id`),
  ADD KEY `а` (`а`),
    [....]
  ADD KEY `ш` (`ш`),
  ADD KEY `ы` (`ы`),
  ADD KEY `ь` (`ь`),
  ADD KEY `ъ` (`ъ`),
  ADD KEY `total` (`total`),
  ADD KEY `а_2` 
    (`а`,`б`,`в`,`г`,`д`,`e`,`ж`,`з`,`и`,`й`,`к`,`л`,`м`,`н`,`о`,`п`,
     `р`,`с`,`т`,`у`,`ф`,`х`,`ц`,`ч`,`ш`,`щ`,`ъ`,`ь`,`ы`,`э`,`ю`,`я`);

我使用查询:

select sql_no_cache `word_id`
    from `vector` use index(а_2)
    where а<=2
      AND б=0 AND в=0 AND г=0 AND д=0 AND е=0 AND ё=0 AND ж=0 AND з=0
      AND и=0 AND й=0 AND к=0 AND л=0 AND м=0
      AND н<=1
      AND о=0 AND п=0 AND р=0 AND с=0 AND т=0 AND у=0 AND ф=0 AND х=0 AND ц=0
      AND ч=0 AND ш=0 AND щ=0 AND ъ=0 AND ь=0 AND ы=0 AND э=0 AND ю=0 AND я=0
      AND word_id != 804272 limit 500

使用组合索引a_2大约需要0.35秒-我如何更快地做到这一点?

分析:

Sending Data    344.5 ms    99.85%  1   344.5 ms
Preparing   157 µs  0.05%   1   157 µs
Statistics  98 µs   0.03%   1   98 µs
Starting    82 µs   0.02%   1   82 µs
[--CUT--]

查询的解释:

id select_type table  type  possible_keys key key_len ref  rows   Extra
1  SIMPLE      vector range а_2           а_2 5       NULL 292073 Using index condition; Using where

不使用索引(а_2)

1 SIMPLE vector ref PRIMARY,а,б,в,г,д,ё,ж,з,и,й,к,л,м,н,о,п,р,с,т,у,ф,...и 1 const 568037 Using index condition; Using where

2 个答案:

答案 0 :(得分:0)

  • 35个索引很多。而且绝不会使用。
  • SELECT ... WHERE total <= 3 AND ... 有时可能会有所帮助,但有时会有所伤害。
  • 以这种方式制定的模式和表没有 good 索引。

如果您要查找带有某些字母的单词,那么我有几个开箱即用的想法。 (有些人会比其他人有更多帮助。)

总计

REGEXP

可以更快地工作。

REGEXP :如果您使用的是MySQL 8.0(具有改进的... AND word REGEXP '^[ан]*$' ... )或MariaDB,则

INT UNSIGNED

可能会导致另一种方法。

:我还考虑使用32位WHERE sorted_word IN ('', 'а', 'аа', 'ан', 'аан', 'н') 来指示哪些字符的计数为非零。

排序:另一个想法是用“已排序”字母对另一列进行排序。然后立即测试

WHERE sorted_word REGEXP '^а{0,2}н{0,1}$'

排序和REGEXP :(速度不快,但更简单):

word

有些人需要将а放在同一张表中并建立索引。

但是,我假设您正在寻找仅包含нtable paragraph has columns : id_paragraph table sentence has columns : id_sentence, id_paragraph table word has columns : id_word, id_sentence, font, color 的简短单词吗?如果这不是您想要的,请详细说明;可能还有其他一些现成的想法会有所帮助。

答案 1 :(得分:0)

索引а_2不包含

ё(我假设您要索引where子句中使用的所有列)。请修复并再次尝试查看速度是否已提高。

第二点:索引列的顺序很重要。将具有高基数的列放在索引的开头会提高速度,但会使索引仅适用于某些选择。