非常感谢您提供任何建议。
我使用的平台是ASP.NET MVC和SQL Server 2005
非常感谢您提供任何建议。
我使用的平台是ASP.NET MVC和SQL Server 2005
我会选择使用单独的查找表。您可以使用以下方式填充它:
INSERT TypeLookup (Type)
SELECT DISTINCT Type
FROM BigMassiveTable
BigMassiveTable
的 INSERT 触发器可以在没有常规批处理作业的情况下完成该工作。 - pilcrowSELECT DISTINCT message_type
FROM message_log
这是最直接但不是非常高效的方法。
如果您有一个可能出现在日志中的类型列表,请使用以下方法:
SELECT message_type
FROM message_types mt
WHERE message_type IN
(
SELECT message_type
FROM message_log
)
如果message_log.message_type
被索引,这将更加高效。
如果您没有这个表但想创建一个,并且message_log.message_type
被索引,请使用递归的CTE
来模拟松散索引扫描:
WITH rows (message_type) AS
(
SELECT MIN(message_type) AS mm
FROM message_log
UNION ALL
SELECT message_type
FROM (
SELECT mn.message_type, ROW_NUMBER() OVER (ORDER BY mn.message_type) AS rn
FROM rows r
JOIN message_type mn
ON mn.message_type > r.message_type
WHERE r.message_type IS NOT NULL
) q
WHERE rn = 1
)
SELECT message_type
FROM rows r
OPTION (MAXRECURSION 0)
SQL Server
缓存数据页面,而不是结果。即使所有表格(或索引)页面都被缓存,仍然需要进行完整的表格或索引扫描。对于足够大的表格,这仍然需要很长时间。 - Quassnoi我只是想说一下显而易见的事情:规范化数据。
message_types
message_type | message_type_name
messages
message_id | message_type | message_type_name
那么你可以不使用任何缓存的 DISTINCT:
对于你的下拉菜单
SELECT * FROM message_types
为您的检索
SELECT * FROM messages WHERE message_type = ?
SELECT m.*, mt.message_type_name FROM messages AS m
JOIN message_types AS mt
ON ( m.message_type = mt.message_type)
我不确定为什么你想要一个需要更新的缓存DISTINCT
,当你可以稍微调整架构并拥有一个带有RI的。
CREATE INDEX IX_Messages_MessageType ON Messages (MessageType)
然后要获取唯一的消息类型(Message Types)列表,你可以运行以下代码:
SELECT DISTINCT MessageType
FROM Messages
ORDER BY MessageType
由于索引按照MessageType的物理顺序排序,SQL Server可以非常快速和高效地扫描索引,获取唯一消息类型的列表。
它的性能并不差 - 这是SQL Server擅长的领域。
可以通过创建一个"消息类型"表来节省一些空间。如果您一次只显示几条消息:那么由于它会与MessageTypes
表连接,所以书签查找不会成为问题。但是,如果您一次显示数百或数千条消息,则连接回MessageTypes可能会变得非常昂贵和无意义,并且将MessageType
存储在消息中将更快。
但是,我对在MessageType
列上创建索引并选择distinct
没有任何问题。 SQL Server喜欢这种东西。但是,如果您发现它对服务器造成了真正的负载,一旦您每秒钟获得数十个点击,那么请遵循其他建议并将它们缓存在内存中。
我的个人解决方案是:
如果我仍然有问题
消息类型应该是主表中指向包含消息类型代码和描述的定义表的外键。这将大大提高您的查找性能。
类似于:
DECLARE @MessageTypes TABLE(
MessageTypeCode VARCHAR(10),
MessageTypeDesciption VARCHAR(100)
)
DECLARE @Messages TABLE(
MessageTypeCode VARCHAR(10),
MessageValue VARCHAR(MAX),
MessageLogDate DATETIME,
AdditionalNotes VARCHAR(MAX)
)
正如其他人所说,创建一个单独的消息类型表。当您向消息表中添加记录时,请检查消息类型是否已存在于该表中。如果不存在,则添加它。在任何情况下,然后将来自消息类型表的标识符发布到消息表中。这应该为您提供规范化的数据。是的,当您添加记录时需要额外的时间,但在检索时应该更有效率。
如果添加的数量比读取的数量多得多,并且“消息类型”很短,则完全不同的方法是仍然创建单独的消息类型表,但在进行添加时不引用它,并且仅在需要时惰性地更新它。
即,(a)在每个消息记录中包含时间戳。 (b)保留上次检查时找到的消息类型列表。 (c)每次检查时,搜索自上次以来添加的任何新消息类型,如下所示:
create table temp_new_types as
(select distinct message_type
from message
where timestamp>last_type_check
);
insert into message_type_list (message_type)
select message_type
from temp_new_types
where message_type not in (select message_type from message_type_list);
drop table temp_new_types;
然后将此检查的时间戳存储在某个地方,以便下次使用。
DISTINCT
子句的查询上索引视图。 - Quassnoi