50 ways to optimize SQL Server

There are many reasons for the slow query speed, the common ones are as follows:
    1. No index or no index is used (this is the most common problem of slow query, and it is a defect of program design)
    2. The I/O throughput is small, forming a bottleneck effect . 3. The query is not optimized because the calculated column is
    not created .
    4. Insufficient memory
    5. Slow network speed
    6. The amount of data queried is too large (multiple queries can be used, and other methods can reduce the amount of data)
    7. Lock or deadlock (this is also the most common problem of slow query, it is the program Design flaws)
    8, sp_lock, sp_who, active user viewing, the reason is that read and write compete for resources.
    9. Unnecessary rows and columns are returned
    10. The query statement is not good and not optimized

The query can be optimized by the following methods:
    1. Put data, logs, and indexes on different I/O devices to increase the reading speed . In the past, Tempdb should be placed on RAID0, but SQL2000 is no longer supported. The larger the amount of data (size), the more important it is to improve I/O. 2. Split the table
    vertically and horizontally to reduce the size of the table (sp_spaceuse)     3. Upgrade hardware     4. According to query conditions, build indexes, optimize indexes, and optimize access methods , Limit the amount of data in the result set . Note that the fill factor is appropriate (preferably using the default value of 0). The index should be as small as possible. Use a column with a small number of bytes to build an index (refer to the creation of the index). Do not build a single index for a field with a limited number of values , such as the gender field     . 5. Improve the network speed;     6. Expand the memory of the server , Windows 2000 and SQL server  2000 can support 4-8G of memory. Configure virtual memory: The virtual memory size should be configured based on the services running concurrently on the computer. When running Microsoft SQL Server 2000, consider setting the virtual memory size to 1.5 times the physical memory installed in the computer. If the full-text search function is additionally installed



 , and intend to run the Microsoft Search service for full-text indexing and querying, consider: Configure the virtual memory size to be at least 3 times the physical memory installed in the computer. Configure the SQL Server max server memory server configuration option to 1.5 times the physical memory (half the virtual memory size setting).
    7. Increase the number of server CPUs ; but it must be understood that parallel processing requires more resources such as memory than serial processing. Whether to use parallel or serial processes is selected by MsSQL's automatic evaluation. A single task is broken down into multiple tasks that can be run on the processor. For example, the sorting, joining, scanning and GROUP BY clauses of delayed queries are executed at the same time. SQL Server determines the optimal parallelism level according to the system load. Complex queries that consume a lot of CPU are most suitable for parallel processing . But update operations UPDATE, INSERT, DELETE cannot be processed in parallel .
    8. If you use like to query, simply using index is not enough, but full-text indexing consumes space. like 'a%' uses an index like '%a' does not use an index. When querying with like '%a%', the query time is proportional to the total length of the field value , so the CHAR type cannot be used, but VARCHAR. Build a full-text index for fields with long values .
    9. DB Server and APPLication Server are separated; OLTP and OLAP are separated
    10. Distributed partition view can be used to realize databaseserver complex. A federation is a group of separately managed servers, but they cooperate with each other to share the processing load of the system. This mechanism of partitioning data to form a database server complex enables the expansion of a group of servers to support the processing needs of large multi-tier Web sites. For more information, see Designing Federated Database Servers. (Refer to the SQL help file 'Partitioned View')
        a. Before implementing a partitioned view, the table must be horizontally partitioned.
        b. After creating a member table, define a distributed partitioned view on each member server, and each view has the same 's name . In this way, queries referencing a distributed partitioned view name can be run on any member server . The system operates as if there is a copy of the original table on each member server, but in reality there is only one member table and one distributed partitioned view on each server. The location of the data is transparent to the application .
    11. Rebuild index DBCC REINDEX, DBCC INDEXDEFRAG, shrink data and log DBCC SHRINKDB, DBCC SHRINKFILE. Set up automatic shrinking log. For large databases, do not set database automatic growth, it will reduce server performance . There is a lot of attention to the writing of T-sql. The common points are listed below: First, the process of DBMS processing query plan is as follows:
            1. Lexical and grammar check of query statement
            2. Query that submits statement to DBMS optimizer
            3. The optimizer performs algebraic optimization and access path optimization
            4. The query plan is generated by the precompiled module
            5. Then it is submitted to the system for processing and execution at the appropriate time.
            6. Finally, the execution result is returned to the user . The structure of data storage: the size of a page is 8K (8060) bytes, and 8 pages are an extent, which is stored according to the B-tree.
    12. The difference between Commit and rollback Rollback: Roll back all transactions. Commit: Commit the current transaction . There is no need to write the transaction in dynamic SQL. If you want to write it, please write it outside. Such as: begin tran exec(@s) commit trans or write dynamic SQL as function or stored procedure.
    13. Use the Where clause in the query Select statement to limit the number of rows returned to avoid table scanning. If unnecessary data is returned, the I/O resources of the server are wasted, which increases the burden on the network and reduces performance. If the table is very large, lock the table during the table scan and prohibit other joins from accessing the table, otherwise the consequences will be serious.
    14. The SQL comment statement has no effect on the execution.
    15. Do not use the cursor as much as possible, it takes up a lot of resources. If you need row-by-row execution, try to use non-cursor techniques, such as: looping on the client side, using temporary tables, Table variables, using subqueries, using Case statements, and so on . A cursor can follow the fetch options it supportsTo sort:
         Forward-only rows must be fetched in order from the first row to the last row. FETCH NEXT is the only fetch operation allowed and is the default.
         Scrollability can randomly fetch any row anywhere in the cursor.
    Cursor technology has become very powerful under SQL2000, and his purpose is to support loops. There are four concurrency options:
         READ_ONLY : Updates via cursor positioning are not allowed, and there are no locks on the rows that make up the result set.
         OPTIMISTIC WITH valueS : Optimistic concurrency control is a standard part of transaction control theory. Optimistic concurrency control is used in situations where there is only a small chance of a second user updating a row in the interval between opening the cursor and updating the row. When a cursor is opened with this option, no locks control the rows in it, which helps maximize its processing power. If the user attempts to modify a row, the row's current value is compared to the value obtained when the row was last fetched. If any value changes, the server knows that someone else has updated the row and returns an error. If the values ​​are the same, the server performs the modification, selecting this concurrency option.
         OPTIMISTIC WITH ROW VERSIONING: This optimistic concurrency control option is based on row versioning. With row versioning, the table must have some version identifier that the server can use to determine whether the row has changed since it was read into the cursor. In SQL Server, this capability is provided by the timestamp data type, which is a binary number that represents the relative order of changes in the database. Each database has a global current timestamp value: @@DBTS. Every time a row with a timestamp column is changed in any way, SQL Server first stores the current @@DBTS value in the timestamp column, and then increments the value of @@DBTS. If a table has a timestamp column, timestamps are recorded at the row level. The server can then compare a row's current timestamp value with the timestamp value stored at the last fetch to determine whether the row has been updated. The server does not have to compare the values ​​of all columns, only the timestamp column. If an application requires optimistic concurrency based on row versioning for a table without a timestamp column, cursors default to optimistic concurrency control based on numeric values.
         SCROLL LOCKSThis option implements pessimistic concurrency control. In pessimistic concurrency control, the application will attempt to lock the database row while it is being read into the cursor result set. When using server cursors, an update lock is placed on the cursor when rows are read into it. If a cursor is opened within a transaction, the transaction update lock is held until the transaction is committed or rolled back; the cursor lock is removed when the next row is fetched. If the cursor is opened outside the transaction, the lock is dropped when the next row is fetched. Therefore, whenever the user needs complete pessimistic concurrency control, the cursor should be opened within a transaction. An update lock will prevent any other task from acquiring an update lock or an exclusive lock, preventing other tasks from updating the row. However, the update lock does not block the shared lock, so it does not prevent other tasks from reading the row unless a second task is also requesting a read with the update lock. Scroll Locks These cursor concurrency options can generate scroll locks based on the lock hints specified in the cursor definition's SELECT statement. Scroll locks are acquired on each row on fetch and held until the next fetch or until the cursor is closed, whichever occurs first. On the next fetch, the server acquires a scroll lock for the row in the new fetch and releases the scroll lock on the row from the previous fetch. Scroll locks are independent of transaction locks and can be held until after a commit or rollback operation. If the option close cursors on commit is off, the COMMIT statement does not close any open cursors, and scroll locks are held after commit to maintain isolation of fetched data. The type of scroll lock acquired depends on the cursor concurrency options and the cursor.     
    16. Use Profiler to track the query, get the time required for the query , find out the problem of SQL; use the index optimizer to optimize the index.
    17. Pay attention to the difference between UNion and UNion all: UNION ALL is good.
    18. Be careful to use DISTINCT. Do not use it when it is not necessary. It will slow down the query like UNION. There is no problem with duplicate records in the query
    19. Do not return unnecessary records when queryingLine, column
    20, use sp_configure 'query governor cost limit' or SET QUERY_GOVERNOR_COST_LIMIT to limit the resources consumed by the query . When the resources consumed by the evaluation query exceed the limit, the server automatically cancels the query, killing it before the query. SET LOCKTIME sets the lock time
    21. Use select top 100 / 10 Percent to limit the number of rows returned by the user or SET ROWCOUNT to limit the rows of operations   
    22. Before SQL2000, generally do not use the following words : "IS NULL", "< >", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'" because they don't go Indexes are all table scans. Do not add functions to the column names in the WHere clause , such as Convert, substring, etc. If you must use a function, create a computed column and then create an index instead . You can also write it differently: WHERE SUBSTRING(firstname,1,1) = ' m' to WHERE firstname like 'm%' (index scan), be sure to separate function and column names. And indexes can't be built too much and too big. NOT IN will scan the table multiple times, use EXISTS, NOT EXISTS, IN, LEFT OUTER JOIN instead, especially left join, And Exists is faster than IN, and the slowest is NOT operation. If the value of the column contains null, its index did not work before, and now the 2000 optimizer can handle it. The same is IS NULL, "NOT", "NOT EXISTS", "NOT IN" can optimize her, but "<>" still can't be optimized , no index is used.
    23. Use Query Analyzer to view the query plan of the SQL statement and evaluate whether the analysis is optimized SQL. Generally, 20% of the code occupies 80% of the resources, and our optimization focus is on these slow places.
    24. If you find that the query does not go to the index when using IN or OR, etc., use the display statement to specify the index : SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN ('male', 'female')
    25. The result of the query will be required Pre-calculated and placed in the table, and then SELECT when querying. This is the most important means before SQL7.0. For example, the calculation of hospital inpatient expenses.
    26. MIN() and MAX() can use appropriate indexes.
    27. There is a principle in the database that the closer the code is to the data, the better, so the priority is to choose Default, followed by Rules, Triggers, Constraint (constraints such as the external health main health CheckUNIQUE..., the maximum length of the data type, etc. are all constraints), Procedure.
    28. If you want to insert a large binary value into the Image column, use a stored procedure, do not use the embedded INsert to insert (I don't know if JAVA is). Because this way the application first converts the binary value to a string (twice its size), and the server converts it to a binary value after receiving the character. The stored procedure does not have these actions: Method: Create procedure p_insert as insert into table( Fimage) values ​​(@image), call this stored procedure in the foreground to pass in binary parameters, so the processing speed is significantly improved.
    29. Between is faster than IN in some cases. Between can find the range based on the index faster . The difference can be seen with the query optimizer. select * from chineseresume where title in ('male','female') Select * from chineseresume where between 'male' and 'female' is the same. Since in will be compared many times, it will sometimes be slower.
    30. Creating indexes on global or local temporary tables when necessary can sometimes improve the speed, but not necessarily because indexes also consume a lot of resources. His creation is the same as the actual table.
    31. Don't build ineffective transactions such as generating reports , wasting resources. Use it only when necessary to use transactions.
    32. The OR clause can be decomposed into multiple queries , and multiple queries can be connected through UNION. Their speed is only related to whether they use an index or not, If the query needs to use a joint index, it is more efficient to use UNION ALL. Multiple OR clauses do not use the index , rewrite it into the form of UNION and then try to match the index. A key question is whether indexes are used.
    33. Use views as little as possible, it is inefficient. The operation on the view is slower than the direct operation on the table , you can use the stored procedure to replace her. In particular, don't use nesting of views. Nested views increase the difficulty of finding source material. Let's look at the essence of the view: it is the optimized SQL stored on the server that has generated the query plan . When retrieving data for a single table, do not use views pointing to multiple tables, retrieve directly from the table or read only the view that contains this table, otherwise unnecessary overhead will be added, and the query will be disturbed. In order to speed up the query of the view, MsSQL increases View index function .
    34. Do not use DISTINCT and ORDER BY when it is not necessary, these actions can be changed to be executed on the client side. They add extra overhead. This is the same as UNION and UNION ALL.
select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667' ,'JCNAD132168','JCNAD00337748','JCNAD00338345',

'JCNAD00333138','JCNAD00303570','JCNAD00303569',
'JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933',
'JCNAD00254567','JCNAD00254585','JCNAD00254608',
'JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618',

'JCNAD00279196','JCNAD00268613') order by postdate desc
    35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数
    36、当用SELECT INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中SELECT * from sysobjects可以看到 SELECT INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事务内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。
    37、一般在GROUP BY 和HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快
    38、一次更新多条记录比分多次更新每次一条快,就是说批处理好
    39、少用临时表,尽量用结果集和Table类型的变量来代替它,Table 类型的变量比临时表好。
    40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:
            a、计算字段的表达是确定的
            b、不能用在text,ntext,Image数据类型
            c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….
    41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源如果返回大的结果采用存储过程
    42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快
    43、SELECT COUNT(*)的效率较低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的!!!
   44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量<最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。
    45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现。
     46、通过SQL Server Performance Monitor监视相应硬件的负载Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。
      Process:
        1、% DPC Time 指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。(DPC 正在运行的为比标准间隔优先权低的间隔)。 由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间 百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部 分。这个总数显示了作为实例时间百分比的平均忙时。
        2、%Processor Time计数器 如果该参数值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。
        3、% Privileged Time 指非闲置处理器时间用于特权模式的百分比。(特权模式是为操作系统组件和操纵硬件驱动程序而设计的一种处理模式。它允许直接访问硬件和所有内存。另一种模式为用户模式,它是一种为应用程序、环境分系统和整数分系统设计的一种有限处理模式。操作系统将应用程序线程转换成特权模式以访问操作系统服务)。 特权时间的 % 包括为间断和 DPC 提供服务的时间。特权时间比率高可能是由于失败设备产生的大数量的间隔而引起的。这个计数器将平均忙时作为样本时间的一部分显示。
        4、% User Time表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。 Physical Disk: Curretn Disk Queue Length计数器该值应不超过磁盘数的1.5~2倍。要提高性能,可增加磁盘。 SQLServer:Cache Hit Ratio计数器该值越高越好。如果持续低于80%,应考虑增加内存。 注意该参数值是从SQL Server启动后,就一直累加记数,所以运行经过一段时间后,该值将不能反映系统当前值。
     47、分析select emp_name form. employee where salary > 3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。
     48、查询的关联同写的顺序
select a.personMemberID, * from chineseresume a,personmember b where personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' (A = B ,B = '号码')
select a.personMemberID, * from chineseresume a,personmember b where a.personMemberID = b.referenceid and a.personMemberID = 'JCNPRH39681' and b.referenceid = 'JCNPRH39681' (A = B ,B = '号码', A = '号码')
select a.personMemberID, * from chineseresume a,personmember b where b.referenceid = 'JCNPRH39681' and a.personMemberID = 'JCNPRH39681' (B = '号码', A = '号码')
     49、
         (1)IF 没有输入负责人代码 THEN code1=0 code2=9999 ELSE code1=code2=负责人代码 END IF 执行SQL语句为: SELECT 负责人名 FROM P2000 WHERE 负责人代码>=:code1 AND负责人代码 <=:code2
         (2)IF 没有输入负责人代码 THEN  SELECT 负责人名 FROM P2000 ELSE code= 负责人代码 SELECT 负责人代码 FROM P2000 WHERE 负责人代码=:code END IF 第一种方法只用了一条SQL语句,第二种方法用了两条SQL语句。在没有输入负责人代码时,第二种方法显然比第一种方法执行效率高,因为它没有限制条件;在输入了负责人代码时,第二种方法仍然比第一种方法效率高,不仅是少了一个限制条件,还因相等运算是最快的查询运算。我们写程序不要怕麻烦
50、关于JOBCN现在查询分页的新方法(如下),用性能优化器分析性能的瓶颈,如果在I/O或者网络的速度上,如下的方法优化切实有效,如果在CPU或者内存上,用现在的方法更好。请区分如下的方法,说明索引越小越好
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by ReferenceID
select * from @local_variable where Fid > 40 and fid <= 60
end 和
begin
DECLARE @local_variable table (FID int identity(1,1),ReferenceID varchar(20))
insert into @local_variable (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from @local_variable where Fid > 40 and fid <= 60
end 的不同
begin
create table #temp (FID int identity(1,1),ReferenceID varchar(20))
insert into #temp (ReferenceID)
select top 100000 ReferenceID from chineseresume order by updatedate
select * from #temp where Fid > 40 and fid <= 60 drop table #temp
end 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325473895&siteId=291194637
Recommended