优化查询多字段mysql
Optimize query many field mysql
我对如何为我的 table 选择最佳索引感到困惑:
有这个table:
Hotel
-has_1
...
-has-5
-nota_AVG
-nota_1
-nota_2
-nota_3
还有这个
Nota_hotel
-nota_1
-nota_2
-nota_3
-id_hotel
来自酒店的名称为 "nota_*" 的字段是从 table Nota_hotel 上的触发器更新的,并且此字段经常更改。
我需要做一些查询,比如
select * from hotel where has_X = true or has_Y=true order by nota_Z
我的子句 "WHERE" 可以有 1 个 has_X 或查询中的许多 has_* 字段取决于选中的复选框。
我想知道放置索引的最佳做法是什么,为每个字段 "nota_" 添加一个索引,为字段 "has_" 创建一个索引(has_1,..., has_5) 或为每个字段 "has_" 添加一个索引,如果有这么多索引可能会扼杀我的 MySQL 服务器 ?
create table hotel(
id int primary key auto_increment,
nume varchar(255),
index hotel_nume_index(nume),
nume_oras varchar(100),
nume_zona varchar(100),
nume_tara varchar(100),
foreign key (nume_oras,nume_zona,nume_tara) references oras(nume,nume_zona,nume_tara) ON DELETE CASCADE,
descriere text,
stele int,
map_x double,
map_y double,
has_sauna TINYINT(1),
has_piscina TINYINT(1),
has_parcare TINYINT(1),
has_restaurant TINYINT(1),
has_fitness TINYINT(1),
distanta_obiectiv double,
code_api1 varchar(255),
code_api2 varchar(255),
code_api3 varchar(255),
intern TINYINT(1),
nota_hotel double,
nota_restaurant double,
nota_locatie double,
nota_conditii double,
nume_comision varchar(100),
foreign key (nume_comision) references comision(nume)
);
create table nota_hotel(
fb_id varchar(100),
data DATETIME,
nota_restaurant double,
nota_locatie double,
nota_conditi double,
comentariu text,
nume_user varchar(255),
id_hotel int,
foreign key (id_hotel) references hotel(id) ON DELETE CASCADE
);
这里是完整的定义
这是一个正在进行的回答。将添加到它。
假设您有 5 个 has_ 列,例如 has_restaurant、has_pool、has_pool 并且像以前一样在真实类型上进行搜索,如 'it is true that it has a pool'
对于初学者,使用 2 的幂将它们转换为一列。让我们称其为 hasX
,其列值是下面的按位或( 不是 列)
has_restaurant (2^0) 1
has_pool (2^1) 2
has_wifi (2^2) 4
has_piscina (2^3) 8
has_sauna (2^4) 16
因此,如果酒店有 wifi 和桑拿浴室,则 hasX 列将(至少)包含值为 20 的位,但可能包含值 21(也有餐厅)。但是搜索是在 'i want wifi and sauna' 上进行的,所以它也找到了 21。这是一个 mask
所以此时我们在第 hasX
列上为酒店添加了一个索引
编辑
我只是对这个概念感到震惊,因为我认为我可以设计一个按位搜索,但在阅读之后这似乎是不可能的。以下似乎是最好的处理方法
CREATE TABLE hotel (
hotel_id int primary key auto_increment PRIMARY KEY,
/* some more fields... */
);
CREATE TABLE hotel_flags (
flag_id TINYINT UNSIGNED NOT NULL
, description VARCHAR(100) NOT NULL
, PRIMARY KEY (flag_id)
);
**the following is the intersect table**
CREATE TABLE hotel_flags_intersect (
hotel_id int not null
, flag_id TINYINT UNSIGNED NOT NULL
, PRIMARY KEY (hotel_id, flag_id)
, UNIQUE INDEX reverse_pk (flag_id, hotel_id)
);
虚心借鉴http://forums.mysql.com/read.php?24,35318,35640#msg-35640
我对如何为我的 table 选择最佳索引感到困惑:
有这个table:
Hotel
-has_1
...
-has-5
-nota_AVG
-nota_1
-nota_2
-nota_3
还有这个
Nota_hotel
-nota_1
-nota_2
-nota_3
-id_hotel
来自酒店的名称为 "nota_*" 的字段是从 table Nota_hotel 上的触发器更新的,并且此字段经常更改。
我需要做一些查询,比如
select * from hotel where has_X = true or has_Y=true order by nota_Z
我的子句 "WHERE" 可以有 1 个 has_X 或查询中的许多 has_* 字段取决于选中的复选框。
我想知道放置索引的最佳做法是什么,为每个字段 "nota_" 添加一个索引,为字段 "has_" 创建一个索引(has_1,..., has_5) 或为每个字段 "has_" 添加一个索引,如果有这么多索引可能会扼杀我的 MySQL 服务器 ?
create table hotel(
id int primary key auto_increment,
nume varchar(255),
index hotel_nume_index(nume),
nume_oras varchar(100),
nume_zona varchar(100),
nume_tara varchar(100),
foreign key (nume_oras,nume_zona,nume_tara) references oras(nume,nume_zona,nume_tara) ON DELETE CASCADE,
descriere text,
stele int,
map_x double,
map_y double,
has_sauna TINYINT(1),
has_piscina TINYINT(1),
has_parcare TINYINT(1),
has_restaurant TINYINT(1),
has_fitness TINYINT(1),
distanta_obiectiv double,
code_api1 varchar(255),
code_api2 varchar(255),
code_api3 varchar(255),
intern TINYINT(1),
nota_hotel double,
nota_restaurant double,
nota_locatie double,
nota_conditii double,
nume_comision varchar(100),
foreign key (nume_comision) references comision(nume)
);
create table nota_hotel(
fb_id varchar(100),
data DATETIME,
nota_restaurant double,
nota_locatie double,
nota_conditi double,
comentariu text,
nume_user varchar(255),
id_hotel int,
foreign key (id_hotel) references hotel(id) ON DELETE CASCADE
);
这里是完整的定义
这是一个正在进行的回答。将添加到它。
假设您有 5 个 has_ 列,例如 has_restaurant、has_pool、has_pool 并且像以前一样在真实类型上进行搜索,如 'it is true that it has a pool'
对于初学者,使用 2 的幂将它们转换为一列。让我们称其为 hasX
,其列值是下面的按位或( 不是 列)
has_restaurant (2^0) 1
has_pool (2^1) 2
has_wifi (2^2) 4
has_piscina (2^3) 8
has_sauna (2^4) 16
因此,如果酒店有 wifi 和桑拿浴室,则 hasX 列将(至少)包含值为 20 的位,但可能包含值 21(也有餐厅)。但是搜索是在 'i want wifi and sauna' 上进行的,所以它也找到了 21。这是一个 mask
所以此时我们在第 hasX
编辑 我只是对这个概念感到震惊,因为我认为我可以设计一个按位搜索,但在阅读之后这似乎是不可能的。以下似乎是最好的处理方法
CREATE TABLE hotel (
hotel_id int primary key auto_increment PRIMARY KEY,
/* some more fields... */
);
CREATE TABLE hotel_flags (
flag_id TINYINT UNSIGNED NOT NULL
, description VARCHAR(100) NOT NULL
, PRIMARY KEY (flag_id)
);
**the following is the intersect table**
CREATE TABLE hotel_flags_intersect (
hotel_id int not null
, flag_id TINYINT UNSIGNED NOT NULL
, PRIMARY KEY (hotel_id, flag_id)
, UNIQUE INDEX reverse_pk (flag_id, hotel_id)
);
虚心借鉴http://forums.mysql.com/read.php?24,35318,35640#msg-35640