加快在非常大的sql表中查找记录的速度

加快在非常大的sql表中查找记录的速度,sql,sql-server,entity-framework,Sql,Sql Server,Entity Framework,对不起,我的英语不好 请假设我们希望保存所有商业操作,即所有日期的销售和购买,并且每天都有 100个或更多动作。三年后,我们有了一张超过100000行的桌子。现在我们想要一个 2年前5月20日至5月25日期间所采取行动的报告 SELECT * FROM actions WHERE Date BETWEEN 2012/5/20 AND 2012/5/25 问题是这样做必须读取所有100000行 首先,我决定将每个月的数据分别放在不同的表中。但我不知道该怎么做 用实体框架处理这个问题。你

对不起,我的英语不好

请假设我们希望保存所有商业操作,即所有日期的销售和购买,并且每天都有

100个或更多动作。三年后,我们有了一张超过100000行的桌子。现在我们想要一个

2年前5月20日至5月25日期间所采取行动的报告

SELECT * 
  FROM actions 
 WHERE Date BETWEEN 2012/5/20 AND 2012/5/25
问题是这样做必须读取所有100000行

首先,我决定将每个月的数据分别放在不同的表中。但我不知道该怎么做

用实体框架处理这个问题。你有什么建议吗?谢谢

问题是这样做必须读取所有100000行

答:即使-那也很简单,除非你用旧手机运行。我定期汇总100亿行表中的1亿行


B:了解索引是什么,那么就不必读取所有的行。

首先,对于SQL Server来说,10万行不会是问题,只要您有正确的索引,即使30年后它也可以正常工作


如果您仍然想拆分它,我不会手动执行,这会造成太多混乱,只需使用表分区,这是由sql server本身处理的,以获取更多信息

不要假设当表中有X行时,查询将表现不好。你应该测试一下

为每个表创建几百万行测试数据非常容易,这些数据应该在开发或测试环境中完成。然后,您可以测试每个查询,看看它们的速度到底有多慢

此代码段将创建一个表并向其中插入1000000行。试试看,试着在上面运行几个不同的查询

CREATE TABLE [dbo].[Orders](
    [OrderId] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
    [CustomerId] [int] NOT NULL,
    [ArticleId] [int] NOT NULL,
    [TotalAmount] [decimal](19, 6) NULL,
    [OrderDate] DATETIME NOT NULL DEFAULT(GETDATE())
);

WITH
            C0(c) AS (SELECT 1 UNION ALL SELECT 1),
            C1(c) AS (SELECT 1 FROM C0 AS A CROSS JOIN C0 AS B),
            C2(c) AS (SELECT 1 FROM C1 AS A CROSS JOIN C1 AS B),
            C3(c) AS (SELECT 1 FROM C2 AS A CROSS JOIN C2 AS B),
            C4(c) AS (SELECT 1 FROM C3 AS A CROSS JOIN C3 AS B),
            C5(c) AS (SELECT 1 FROM C4 AS A CROSS JOIN C4 AS B),
            C6(c) AS (SELECT 1 FROM C5 AS A CROSS JOIN C5 AS B),

        numbers(n) AS(
                        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
                FROM C6)

INSERT dbo.Orders
        ( CustomerId ,
          ArticleId ,
          TotalAmount,
          OrderDate
        ) 
SELECT TOP 1000000
        N % 150 + 1, 
        N % 100 + 1, 
        N % 500 + 20,
        DATEADD(MINUTE, (N - 1), '2014-01-01')
FROM numbers;
该表将包含100种不同商品的100万份订单,由150名不同的客户完成,每个订单的金额在20至520之间。从2014-01-01 00:00:00开始,每个订单之间间隔一分钟

使用该数据,在我的工作站上,以下查询仍在不到1秒的时间内执行:

SELECT * FROM dbo.Orders WHERE orderDate BETWEEN '2014-05-01' AND '2014-08-01' 
磁盘上的数据往往比您想象的要小得多。这个包含一百万行的表仍然只占用大约70MB的空间

EXEC sys.sp_spaceused @objname = N'Orders'
--name      rows        reserved    data        index_size  unused
--Orders    1000000     70432 KB    37560 KB    32072 KB    800 KB
从磁盘读取这么多MB需要多长时间?2-3秒,桌面上最坏的情况

添加索引: 评论其他答案

我在date列上添加了一个索引,但查询优化器仍然认为最好扫描整个表。这可能是因为对日期范围内的所有订单执行查找比从磁盘顺序读取要昂贵。根据表中的数据,这些索引可能会被使用,也可能不会被使用。这就是为什么您应该生成与预期负载匹配的测试数据,只有这样您才能优化查询并创建正确的索引


对于这个特定的表,也可能是问题中的表,我建议将聚集索引放在日期列而不是主键上。

您能为B部分做更多解释吗?是的。买本书。例如,用于傻瓜的Sql。读一下。您缺乏绝对sql基础知识。谢谢zahorak。我看到在我的朋友项目中,阅读500000行需要10分钟!你认为这一次不好,他们有一个未知的问题吗?这取决于行的类型和它读取的数据,一行有4个数字列与一行有8KB的数据是不同的-如果你想从那里读取所有数据而不使用索引,那么你需要处理4GB的8K*500000数据。但是,正如在另一个答案中提到的,使用索引将有助于解决很多问题。你要问的是关于索引、分区等问题。建议你阅读一本书或参考在线资料。