【发布时间】:2016-07-09 15:23:12
【问题描述】:
我有兴趣为处理大量相似数据条目的应用程序设计基于 SQL(实际上是 SQLite)的存储。对于这个例子,让它成为一个聊天消息存储。
应用程序必须提供按消息参与者、标签等过滤和分析数据的能力,所有这些都暗示着 N 对 N 关系。
因此,架构(星型)将类似于:
create table messages (
message_id INTEGER PRIMARY KEY,
time_stamp INTEGER NOT NULL
-- other fact fields
);
create table users (
user_id INTEGER PRIMARY KEY,
-- user dimension data
);
create table message_participants (
user_id INTEGER references users(user_id),
message_id INTEGER references messages(message_id)
);
create table tags (
tag_id INTEGER PRIMARY KEY,
tag_name TEXT NOT NULL,
-- tag dimension data
);
create table message_tags (
tag_id INTEGER references tags(tag_id),
message_id INTEGER references messages(message_id)
);
-- etc.
所以,一切都很好,直到我必须执行基于 N 到 N 维度的分析操作和过滤。鉴于 messages 表中有数百万行和数千个维度(示例中显示的数据不止这些),所有连接对性能的影响都太大了。
例如,我想分析每个用户参与的消息数量,假设数据是根据选择的标签、选择的用户和其他方面过滤的:
select U.user_id, U.user_name, count(1)
from messages as M
join message_participants as MP on M.message_id=MP.message_id
join user as U on MP.user_id=U.user_id
where
MP.user_id not in ( /* some user ID's set */ )
and M.time_stamp between @StartTime and @EndTime
and
-- more fact table fields filtering
and message_id in
(select message_id
from message_tags
where tag_id in ( /* some tag ID's set */ ))
and
-- more N-to-N filtering
group by U.user_id
我受限于 SQL,特别是 SQLite。而且我确实在表格上使用了索引。
我看不出有什么方法可以改进架构,也许是一种聪明的方法来去规范化它?
或者也许有一种方法可以以某种方式索引消息行中的维度键(我考虑过使用 FTS 功能,但不确定搜索文本索引并加入结果是否会提供任何性能影响)?
【问题讨论】:
-
能否提供一个执行不佳的示例 SQL 语句?
-
@trincot 查看示例
-
你是否为所有外键定义了索引?
-
@trincot 是的,这不是问题。
-
那么我看不出为什么示例语句不能快速运行,即使有数百万条记录,尽管您可能想要添加一个限制子句。
标签: sql performance sqlite data-warehouse