MySql数据库当分析型数仓去使用吧。
MySql当作列存数据库(
OLAP分析型数仓)使用时多条件
and查询如何实现。
n列,那么把一行记录按列存储后就需要存约
n-1行记录。同时,转为列存后每行都需要多出几列标记这一条记录属于哪个“行记录”,以及存储的是“行记录”哪一列的值。
tb_row_user表结构如下。
tb_column_user结构如下。
tb_row_user里面插入一条记录。
tb_column_user插入如下
3条记录。
user_id、
column_name、
column_value分别创建索引。
25岁且性别为男的所有用户的
id,我们应该怎样写
sql?现在条件只有两个,假如条件有
5个,
10个呢?
select user_id,count(id) as cnt
from tb_column_user where
(column_name = 'age' and column_value > '25')
or
(column_name = 'sex' and column_value = '男')
group by user_id having cnt = 2;
group by去掉,那么
sql就是查询条件满足
age大于
25或者性别是男的用户,即。
select user_id from tb_column_user where
(column_name = 'age' and column_value > '25')
or
(column_name = 'sex' and column_value = '男');
user_id就会有两条记录,否则如果只满足其中一个条件,那么查询结果这个
user_id就只会有一条记录。比如:
>25) |
=男) |
user_id分组统计得到的
cnt就是匹配的条件个数,最后通过
having就可以筛选出同时满足两个条件(
having cnt = 2)的用户的
id。
sql更便于动态拼接,不过使用这个
sql有个前提条件,要求
tb_row_user表里面的每一行记录的每一列对应到
tb_column_user表都只有一行记录(也可以没有)。
SQL的执行计划如下:

OR查询,因此
Type为
index,即全索引扫描(遍历索引树),因此性能会随着数据量的增加而越来越慢。
join查询,
sql如下:
select u1.user_id from tb_column_user as u1 inner join (
select user_id from tb_column_user where column_name = 'sex' and column_value = '男'
) as u2
where u1.user_id=u2.user_id and u1.column_name = 'age' and u1.column_value > '25';
sql的执行计划如下。

sql就会看得很头疼了:
select u1.user_id from tb_column_user as u1 inner join (
select uu1.user_id from tb_column_user uu1 inner join(
select user_id from tb_column_user where column_name = 'tag' and column_value = '穷'
)uu2
where uu1.user_id=uu2.user_id and uu1.column_name = 'sex' and uu1.column_value = '男'
) as u2
where u1.user_id=u2.user_id and u1.column_name = 'age' and u1.column_value > '25';

join查询每个查询都能用到索引,并且外层查询扫描的行数总比内层查询扫描的行数少,经过了层层过滤,最终扫描的行数就是最内层的查询语句所扫描的行数。
总结
sql清晰易读,缺点是性能差;
sql看着越难理解。
文章转载自Java艺术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




