多列索引与每列的索引?mysql
我有以下表格: 业务表:多列索引与每列的索引?mysql,mysql,sql,database,indexing,Mysql,Sql,Database,Indexing,我有以下表格: 业务表: bussId | nameEn | nameHe | nameAr | status | favor | cityId | categoryId categoryId | keywords userId | bussId userId | bussId | rating 类别表: bussId | nameEn | nameHe | nameAr | status | favor | cityId | categoryId categoryId | key
bussId | nameEn | nameHe | nameAr | status | favor | cityId | categoryId
categoryId | keywords
userId | bussId
userId | bussId | rating
类别表:
bussId | nameEn | nameHe | nameAr | status | favor | cityId | categoryId
categoryId | keywords
userId | bussId
userId | bussId | rating
喜爱的表格:
bussId | nameEn | nameHe | nameAr | status | favor | cityId | categoryId
categoryId | keywords
userId | bussId
userId | bussId | rating
评级表:
bussId | nameEn | nameHe | nameAr | status | favor | cityId | categoryId
categoryId | keywords
userId | bussId
userId | bussId | rating
我正在运行这个查询,它使用cityId和搜索(business.nameEn、business.nameAr、business.nameHe、categories.keywords)过滤企业,然后按偏好、状态和名称排序
SELECT DISTINCT bussID ,businessName, bussStatus,favor, ratingCount , ratingSum
FROM
(
SELECT DISTINCT business.bussID , business.nameEn as businessName , bussStatus,favor,
(SELECT COUNT(rating.bussId) FROM `rating` WHERE rating.bussId = business.bussID) as ratingCount ,
(SELECT SUM(rating.rating) FROM `rating` WHERE rating.bussId = business.bussID) as ratingSum
FROM business LEFT JOIN favourites ON (favourites.bussID = business.bussID AND favourites.userID = '30000')
INNER JOIN `categories` ON (`categories`.`categoryId` = `business`.`subCategoryId` )
WHERE (bussiness.cityID = 11)
AND (
( REPLACE( REPLACE(REPLACE(LOWER(`bussiness`.`nameEn`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
OR( REPLACE( REPLACE(REPLACE(LOWER(`bussiness`.`nameHe`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
OR( REPLACE( REPLACE(REPLACE(LOWER(`bussiness`.`nameAr`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
OR( REPLACE( REPLACE(REPLACE(LOWER(`categories2`.`keyWords`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
)
AND
(bussiness.bussStatus IN(1,3,5,7)
)
GROUP BY bussiness.bussID )results
ORDER BY
businessName LIKE '%test%' DESC,
FIELD(bussStatus,'1','5','3'),
FIELD(favor,'1','2','3'),
businessName LIMIT 0,10
我正在使用replace搜索不区分大小写的أا
和㶡ه
字母(在添加测试词之前,我也替换这些字母)
我的问题:
ALTER TABLE `bussiness`
ADD INDEX `index9` (`nameHe` ASC, `nameEn` ASC, `nameAr` ASC, `favor` ASC, `bussStatus` ASC);
或者每个列有一个列索引
allNamesLanguages
,其中包含nameAr、nameEn、nameHe
,然后我只搜索这个列函数基本上使索引无用。因此,在
WHERE
子句中使用的列,如UPPER(name)
和else,可以通过所谓的“基于函数的索引”进行索引。它们是Oracle的一个功能,但据我所知,MySQL中没有
不过,基于函数的索引有其先决条件。所使用的函数必须是确定性的。所以,如果你想索引一个像“年龄”这样的计算,它将不起作用,因为定义为“现在减去然后”的“年龄”基本上在每次选择时都会增长
我的建议是创建更多的列,并尽可能地存储要挖掘的信息
如果像“%blabla%”这样使用,由于文本起始长度可变,任何索引都将无效。因此,请尝试组织额外的列,这样您就可以避免像“%…
这样的或根本避免像“
这样的了。根据我的经验,向索引中添加更多的列不会阻碍许多列的性能。因此,只要尝试一下如果为它们添加4列和一个组合索引会发生什么情况
据我所知,只要你能写下:
... WHERE nameEn_idx = 'test' AND/OR nameEr_idx = 'test' ...
这部分查询存在两个问题,导致标准索引无法使用:
( REPLACE( REPLACE(REPLACE(LOWER(`bussiness`.`nameEn`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
OR( REPLACE( REPLACE(REPLACE(LOWER(`bussiness`.`nameHe`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
OR( REPLACE( REPLACE(REPLACE(LOWER(`bussiness`.`nameAr`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
OR( REPLACE( REPLACE(REPLACE(LOWER(`categories2`.`keyWords`),'أ','ا'),'أ','ا') ,'ة','ه') LIKE '%test%' )
第一个是在列上使用函数。第二个是使用like
和以通配符('%'
)开头的模式
对于您似乎想要的功能,您需要使用全文索引、触发器和其他列
以下是我的建议:
- 添加(至少)四个用于搜索姓名的附加列。类似于
business.nameEn\u search
等
- 添加
insert
——可能还有update
和delete
触发器,它们将在插入新值时替换特殊字符。也就是说,触发器中包含大量的replace(…)
逻辑
- 为四列添加全文索引
- 使用
match…(匹配)
进行查询
有关全文功能的更多信息,请参见。并非“业务”的拼写如此。至于索引,为什么不吸一下看看?@草莓我怎么知道我的查询使用了哪些索引!解释会告诉你(我是说“注意”,而不是“不”),这是重复的吗?如果我创建了一个col,谢谢你的回答。”nameEn\u nameAr\u name\u搜索“组合3列,然后只创建一个索引!好吗?2问:我正在使用Innodb引擎,使用全文和匹配是否有问题。。。反对?谢谢,那么创建一个包含四列的列,然后为该列创建一个全文怎么样?哦,根据mysql,需要5.6.4和更高版本,但我使用的是5.6.21b:(感谢您的回复,但这对我没有帮助,因为根据您的查询,名称为testXY的业务将不会返回!还要注意,排序规则utf8\u unicode\u ci和utf8\u persian\u ci会进行大小写折叠。因此,UPPER()
和LOWER()
是不必要的。