提高SQL Server数据库性能实体框架

本文关键字:实体 框架 性能 数据库 SQL Server 提高 | 更新日期: 2023-09-27 18:06:37

我已经创建了一个已经进入生产的应用程序,它有几个表,如下所示。

我对每个表都有一个类似于下面的搜索查询。数据库每天以几千行的速度增长,我很担心性能的提高。

谁能建议我应该如何重新设计这个过程以提高效率?

我正在使用实体框架,c#和SQL Server。

是否有可能估计像这样的数据库的系统资源需求?比如说,如果我有60万行?

提前感谢您的回复!

select top 100 * 
from table 
where given_name.contains(search) 
   or family_name.contains(search) 
   or session_number.contains(search)
表结构:

[id] [int] IDENTITY(1,1) NOT NULL,
[given_name] [nvarchar](100) NULL,
[family_name] [nvarchar](100) NULL,
[session_number] [nvarchar](100) NULL,
[birth_date] [datetime2](7) NULL,
[start_date] [datetime2](7) NULL,
[reported_date] [datetime2](7) NULL,
[confirmed_date] [datetime2](7) NULL,
[dir_name] [nvarchar](100) NULL,
[info] [text] NULL,
[complete] [bit] NULL,
[approved_by] [uniqueidentifier] NULL,
[reported_by] [uniqueidentifier] NULL,
[code] [nvarchar](10) NULL,
[sex] [bit] NULL,
[emergency] [bit] NULL,
[release] [bit] NULL,
[stop] [bit] NULL,

提高SQL Server数据库性能实体框架

600,000行并不是那么多行,所以实际上你可以继续使用你的方法。

如果它会增加,有一个问题和一个潜在的问题:

  • 查询有Contains子句,EF将其转换为类似于'%%'模式的SQL。优化器不会在given_name、family_name和会话号上使用索引。你可以评估Ef不直接支持的SQL Server全文搜索,但有一些库(几行代码)来启用支持。你可以在这里找到其中一个http://www.entityframework.info/Home/FullTextSearch

  • 第二个问题与OR优化有关,如果有正确的索引(不是你的情况!!)。在这种情况下,DBMS可以以两种方式工作:

    1. 表扫描WHERE子句
    2. 检索3个不同的临时表(每个OR条件1个),而不是进行UNION(不是UNION ALL,成本较低,但结果不同)。UNION是表的合并,所以如果有几个记录,DBMS可以对临时表进行排序,或者只是对3个临时表进行表扫描(在REC_ID上排序,而不是在用于解决or子句的索引上排序)

在这两种情况下都是非常昂贵的方法,但是如果你真的需要OR子句是最好的方法。此外,DBMS处理索引统计数据,因此它可能比程序员的选择更好(我们希望如此)。

如果你不介意有重复的记录,你可以将查询拆分为3个不同的查询,并创建一个sql UNION (LINQ中的Concat)。要小心,因为对多个OR条件适用的单个记录将出现更多次。

我认为您可以创建一个存储过程来处理您的搜索。此外,为了避免OR,您可以使用全文。然后在存储过程中使用全文搜索,如下所示:

CREATE PROCEDURE prc_SearchTable
    @searchTerm VARCHAR(100) 
    -- searchTerm should be like *john*
AS 
BEGIN
    SELECT *
    FROM   theTable
    WHERE  CONTAINS((given_name,family_name,family_name), @search)
END

请确保为全文搜索* term *添加通配符(不含空格)。

您可以像下面所描述的那样向EF添加存储过程