在这种情况下,MySql单列索引或多列索引

时间:2015-05-13 10:56:27

标签: mysql indexing sql-like

我有以下简化表'places',其中包含200,000多行:

placeId INT(10)
placeName VARCHAR (30)
placeNameEnglish VARCHAR (30)
  • placeName是以原始语言存储的地名,例如的罗纳
  • placeNameEnglish是一个翻译成英文的地名,例如的罗纳

目前我有两个单列索引 - 一个用于placeName,另一个用于placeNameEnglish,我正在进行这些LIKE模式查询:

$testStr = 'rho';

SELECT placeId
FROM places
WHERE (placeName LIKE '$testStr%' OR placeNameEnglish LIKE '$testStr%')

完成了一些研究但在这种情况下使用时无法完全理解多列索引。问题是,我应该将placeNameplaceNameEnglish合并到多列索引中还是将它们作为单独的索引保留?

更新

致力于实施@Gordon Linoff提出的最后建议。

考虑添加名为translations而不是placeNames的表,以便可以将相同的索引用于多个表,即需要相同persons匹配的LIKE 'abc%'表。

到目前为止:

transId INT

parentId INT - placeIdpersonId

parentTypeId TINYINT - 1标识places表或2persons等等(更多表格可以在以后使用此系统日期)

languageId INT

transName VARCHAR

我是否还要将parentTypeId编入索引以适应识别正确父表所需的额外WHERE条件?

e.g。 WHERE transName LIKE 'abc%' AND parentTypeId = 1

我想mysql的工作原理如下:它首先使用transName的索引与transName LIKE 'abc%'匹配,然后使用parentTypeId = 1

过滤结果

2 个答案:

答案 0 :(得分:1)

对于此查询:

SELECT placeId
FROM places
WHERE placeName LIKE '$testStr%' OR placeNameEnglish LIKE '$testStr%';

MySQL 可以使用两个索引,一个在places(placeName)上,一个在places(placeNameEnglish)上。该操作是一个称为索引的合并(参见here)。我不会指望它。此查询无法完全使用复合索引。

您可以将查询重新命名为:

SELECT placeId
FROM places
WHERE placeName LIKE '$testStr%'
UNION
SELECT placeId
FROM places
WHERE placeNameEnglish LIKE '$testStr%';

或:

SELECT placeId
FROM places
WHERE placeName LIKE '$testStr%'
UNION ALL
SELECT placeId
FROM places
WHERE placeId NOT IN (SELECT placeId FROM places WHERE placename LIKE '$testStr%') AND
      placeNameEnglish LIKE '$testStr%';

这些可以利用这两个索引。

但我的建议是更改数据结构。有一个名为PlaceNames(或类似的东西)的表,其中包含以下列:

placeNameId INT
placeId INT,
languageId INT,
placeName VARCHAR(255)

也就是说,每种语言都有一个单独的行。然后,您的查询可以轻松利用placeName(placeName)上的索引。

答案 1 :(得分:0)

原始问题:两个单独的INDEX。但是......你工作太辛苦了:

对于欧洲地名,您无需搜索两列。 utf8_unicode_ci(或utf8_bin以外的任何排序规则)的案例折叠和重音不敏感性将满足您的需求:

mysql> SELECT 'Rhône' LIKE '%rho%', 'Rhône' LIKE '%xyz%';
+-----------------------+-----------------------+
| 'Rhône' LIKE '%rho%'  | 'Rhône' LIKE '%xyz%'  |
+-----------------------+-----------------------+
|                     1 |                     0 |
+-----------------------+-----------------------+

编辑根据OP的评论,这不是一个完整的解决方案。