我有以下简化表'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%')
完成了一些研究但在这种情况下使用时无法完全理解多列索引。问题是,我应该将placeName
和placeNameEnglish
合并到多列索引中还是将它们作为单独的索引保留?
致力于实施@Gordon Linoff提出的最后建议。
考虑添加名为translations
而不是placeNames
的表,以便可以将相同的索引用于多个表,即需要相同persons
匹配的LIKE 'abc%'
表。
到目前为止:
transId INT
parentId INT
- placeId
或personId
parentTypeId TINYINT
- 1
标识places
表或2
表persons
等等(更多表格可以在以后使用此系统日期)
languageId INT
transName VARCHAR
我是否还要将parentTypeId
编入索引以适应识别正确父表所需的额外WHERE
条件?
e.g。 WHERE transName LIKE 'abc%' AND parentTypeId = 1
我想mysql的工作原理如下:它首先使用transName
的索引与transName LIKE 'abc%'
匹配,然后使用parentTypeId = 1
答案 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的评论,这不是一个完整的解决方案。