Presentation is loading. Please wait.

Presentation is loading. Please wait.

SQL Server™ 2000에서 성능 좋은 어플리케이션 구현하기

Similar presentations


Presentation on theme: "SQL Server™ 2000에서 성능 좋은 어플리케이션 구현하기"— Presentation transcript:

1 SQL Server™ 2000에서 성능 좋은 어플리케이션 구현하기
(Building High Performance Applications With SQL Server™ 2000) 우 철웅 ㈜인브레인 기술이사

2 세션의 목적 어플리케이션 개발자 관점에서 SQL 서버의 확장성과 수행 속도에 대한 논의
성능 좋은 어플리케이션을 만들기 위한 예제 The SQL development team spends a tremendous amount of time and effort working with ISV partners to better understand the characteristics of their application suites with respect to performance and scaling. You can consider performance to be the time (or similar metric) that an end user at a screen (or in a batch program to process the necessary data. Scaling could refer what happens to the backend and the network as the number of users scales and whether there are any bottlenecks or other issues with the resources that you have available By working with some of our partners, we have broken down the issues and looked at bottlenecks to understand the performance improvements that we could make in SQL2000, as well as best app dev practices In this session, I would like to talk about SQL server performance and scalability from the aspect of the database driver in your application suite – how your application interacts with SQL Server What are the tips that we have seen about performance characterizations in running against SQL dbms.

3 SQL 서버 성능 관리 Self Configuring, Managing, Tuning
자동화된 memory/lock/object 관리 확장되고 스마트한 I/O 복합 구문에 대한 병행 실행 계획 자동화된 미리 읽기(Readahead) 자동화된 통계정보의 생성/관리 고급 쿼리 최적화 자동화된 인덱스 튜닝 관리 자동화된 쿼리 실행 계획의 캐싱 기타, 여러 가지… A major design anchor and philosophy for SQL Server is for self management of the database system based on requirements and the resources available. This takes the form of the system performing self configuration, management and tuning. Memory is a dynamic resource - the buffer pool and its associated data structures grow and shrink automatically … This is very tightly coupled with the NT memory manager, allowing queries to quickly get and use large amounts of memory if there are not extra requirements on the system We have dynamic locking - When modifying individal rows … take row locks to maximize concurrency … I.e. oltp, order entry When scanning larger volumes of data, take page or table locks to minimize the cpu and other resource close of getting locks - THIS IS ALL DONE AUTOMATICALLY at runtime The system will do automatic creation of statistics when needed on non-indexed columns – this feature can be turned off with a configuration parm It will also recognize that stats are out of date. In this case it will refresh the stats by page sampling – this can also be turned off … The sampling for stats gathering is very fast (about 1 to 5 seconds). There is a default algorithm … File groups allow for the logical grouping of one or more files to provide data placement capabilities These are Virtually invisible for the low end But very scalable for the high – end systems and facilitates parallel scans and other intelligent scan techniques to get data off disk quickly and make effective use of the disks and I/O sub systems available .. The database will efficiently grow and shrink are required. And there is so much more ….. But these features are of interest to folks in production (our common customer) what impacts folks building applications

4 “SQL 서버의 성능은 좋은데, 왜 나의 어플리케이션은 그렇지 못한가?”
어플리케이션 수행속도와 확장성을 위해 살펴 보아야 할 내용 최적화된 실행 계획의 케싱 보장 네트웍 라운드트립(roundtrip)의 최소화 효과적인 커서의 사용 데이터를 접근하는 방법에 따라 수행 속도의 결과는 굉장한 차이를 보일 수 있다. I want to talk about what you can affect directly and immediately from an application development stand point to get optimal performance and allow scaling of a large number of concurrent users. First I want to talk about how application suites use the plan cache, the various methods, the performance implications and our recommendations. I would then like to talk about cursors, their effects on the server resources, performance and again our recommendations. Throughout these 2 topics, I will be talking about enhancements that we did in SQL2000 that help performance and scalability and other general topics that affect application developers like you. Please note that In addition to the performance enhancements in the areas of plan caching and cursors in SQL 2000, there are many more performance enhancements in 2000, that my colleagues have covered this week: Indexed views - pre-aggregation, pre-join Improved statistics - better plans Many plan improvements - new plans considered, improved costing Bitmap filtering in joins - more efficient joins Better execution of parallel plans - many improvements Better memory grant and degree-of-parallelism algorithms - improvements for concurrent DSS7. Parallel index build Better synchronization in parallel sort - higher scalability with #processors Faster scans - multiple 100s of MB/s Faster random I/Os - > 100MB/s Merry-go-round scans - one scan used by multiple consumers More intelligent buffer pool policies for scans versus indexes Use of AWE memory (> 3GB) for buffer pool Better support for partitioned views - local and remote (Coyote) as well

5 실행 계획의 캐싱 아키텍쳐 살펴보기 쿼리한 SQL 구문은 파서에 의해 쿼리 트리로 만들어 진다.
옵티마이저는 최적화된 실행 계획을 만들기 위해 쿼리 트리를 만든다. 정규화 (Normalization) 통계 정보를 이용한 최적화 (비용 기준) 가장 빠른 경로를 위한, 최소 비용 처리 방법 발견 실행 계획 – 데이터 구조 생성 실행 계획의 저장 같은 실행 컨택스트 내에서 재사용 What is the plan cache – and why is it important ? SQL commands are taken by the command parser that check for the proper syntax and is translated into an internal format known as a query tree - Optimizer will take the query tree and prepares it for execution by compiling and optimizing the queries The result of the query optimization and compilation result is the execution plan First step is to normalize the query, by breaking it down into smaller individual requirements It will then optimize the overall query – which basically means finding an optimal execution plan. The new optimizer that we introduced in SQL7 is cost base – - I.e. choose the least cost based plans based on internal metrics like minimization of I/O, CPU requirements, and use of the buffer cache memory. It looks at the amount of data in the tables involved, the indexes available to it, and the statistical distribution of the data It will also prune heuristics to make sure that it does not consider too many options for the overall benefit of running the query effectively After optimization, a execution plan is generated which has 2 components: Query plan – reentrant, read-only data structure - with “commands” that specifies the order of the table, indexes and criteria (generally from the where clause) that must be satisfied. There can be 2 copies of this – 1 for a serial and the other for parallel plan Execution context – each user executing this query has a data structure with context data … Why is this important – Execution plans are stored in a plan cache (also called procedure cache) …. When a user specifies a query, SQL will check in here for an existing plan – if found, there is no need to compile and optimize the statement For non-trivial SQL statements, this can be a very important savings …. We are saving cpu resources. In fact we have see where compiling and optimizing an execution plan in ERP application can take 3-4 times the cpu of executing the plan.

6 실행 계획의 케싱(Caching) 케싱 메커니즘의 형태
임의 질의에 대한 케싱 임의 질의(Ad-hoc) 케싱 자동 파라메터화 고정된 질의에 대한 케싱 저장 프로시저 ExecuteSQL Prepare/Execute/Unprepare There are techniques that both the system and you the application developer can use to try to make effective use of the plan cache – in other words use post-optimized plans that are already cached in memory, and which help you scale the number of concurrent users that you can have on a system…. SQL Server on its own will use 2 techniques to make effective use of the plan cache – ad-hoc caching and auto parameterization. These are very conservative in their implementation. For a scalable system, you should not rely on these system techniques – please use techniques for defined workloads, as you are aware of the functionality in your application and how it will be used. These include stored procedures, executesql, and the prepare/execute model. We need to talk about sharing rules for Plan Caching Sharing: For plans to be shared between users, and thus maximize the effectiveness of the caching mechanisms, follow the sharing rules: Insure all users execute in the same environment. Don't change SET or database settings in the middle of an application or connection. The environment is determined by Server-settings (sp_configure), database-settings (sp_dboption), and connection-settings (SET option) Insure batches/procedures don't require implicit resolution except where absolutely necessary I.e. An implicit resolution occurs when determining what an object is requires knowing who is asking. For instance: select * from DB..FOO means DB.Mary.Foo when Mary is executing and DB.Jane.FOO when Jane is executing – a plan compiled by Mary would probably not be able to be reused by Jane Implicit Resolutions A plan can only be shared with other users if the plan contains no implicit resolutions. Mary and Jane are two users in database DB. Both have objects named Foo. A query: select * from DB..FOO means select * from DB.Mary.FOO if Mary is executing the query, whereas it means select * from DB.Jane.FOO if Jane is executing the query. Thus, the query requires implicit resolution to determine what it means. A batch/procedure compiled by Mary with this query could not be used by anyone except Mary.

7 임의 질의에 대한 케싱 어떻게 작업하는가? 임의 질의 구문에 대한 실행 계획 케싱
정확히 같은 구문을 수행한다면 케시된 수행계획을 재 사용 예 : Q1: select * from employees where fname like ‘S%’ Q2: select * from employees where fname like ‘D%’ Q3: select * from employees where fname like ‘S%’ Q3 는 Q1의 케시된 실행 계획을 사용하게 된다. Q2 컴파일을 필요로 한다. Lets talk about the simples form of caching – this is performed by the system. SQL caches the plans from adhoc batches, and if a subsequent batch matches exactly, it will use the cached plan. This feature requires no extra work to use - but is limited to exact textual matches. E.g. given: In this example Q#3 will use the cached plan from Q#1, but Q#2 will have to be compiled from scratch. This is barely useful when we talk about large scalable systems with many users. This is really SQL Server looking to save some execution time for the user in an ad-hoc case Query plans produced from reuse if the identical Transact-SQL statement is later executed. an ad hoc Transact-SQL query, including auto-parameterized queries. SQL Server caches the plans for ad hoc SQL statements for later

8 자동 파라메터화 어떻게 작업하는가? 단순 구문에 대해서만 처리된다. 옵티마이저는 상수에 대해 파라메터화 할 것인지 검토한다.
자동 파라메터화 어떻게 작업하는가? 단순 구문에 대해서만 처리된다. 옵티마이저는 상수에 대해 파라메터화 할 것인지 검토한다. 만약 파라메터화가 결정되면 템플릿 실행 계획은 캐시에 저장된다. 연속적으로 동종의 쿼리가 수행되어 캐시의 저장된 템플릿 실행 계획을 사용한다면 “safe”로 만들것을 고려한다. 권고 사항: 잘 정의된 작업에 대해 이런 기능을 믿고 작업하지는 않는 것이 좋겠다. A second more useful technique employed by SQL Server 2000 is auto-parameterization. This is for simple queries – SQL makes an educated guess on what constants and literals could really be parameters. For example: Select LastName, Salary from employees where employee_ID =1000 It could make the 1000 into a parameter ….. A subsequent query of the same form but check employee number 1200 would use the parameterized parameter This process is very conservative … and might not auto-parameterize a query in question IMPORTANT: PLEASE DO NOT Rely on this for defined workloads such as in your application suite. SQL Server is making an educated guess on which constants and literals could be in actuality parameters … You know when building your application.

9 자동 파라메터화 지원하는 기본 구문 INSERT <table> VALUES ({constant} | NULL | DEFAULT}, ..) DELETE <table> WHERE <key-exp> UPDATE <table> SET <col> = <constant> WHERE <key-exp> SELECT <col-list> FROM <table> WHERE <key-exp> ORDER BY <col-list> For full disclosure: here are the forms of queries that SQL Server will consider for auto-parameterization: Inserting values into a table where there are in constant/literal form, NULL or DEFAULT Deleting from a table with a key expression where the key expression could be columns, constants and operators like AND, <,> = etc. Updating a table setting a column and a where clause where the key expression again could be columns, constants and operators such as AND, <, > = etc. Selecting columns from a table where there could be a key expression again, and perhaps the ORDER BY clause…..

10 자동 파라메터화 템플릿 예제 Safe: Unsafe: 옵티마이저의 이러한 결정은 매우 보수적이다.
자동 파라메터화 템플릿 예제 Safe: SELECT fname, lname FROM employees WHERE emp_id Unsafe: SELECT fname, lname FROM employees WHERE (salary + bonus) > 30000 옵티마이저의 이러한 결정은 매우 보수적이다. I had mentioned a safe example – selecting the name from employees where the employee number was 1000 This would be auto-parameterized ….. And the template reused when looking for employee 1200 An unsafe SQL query for auto-parameterization would be when SQL could not deterministically decide that the query would have the same plan when the parameter change. In this example, if a subsequent query were to specify salary + bonus greater that 100K … the result set could be drastically different (especially depending on the indexes) and another plan could be chosen …. This would not be auto-parameterized, based on the discussion ….. Again – its IMPORTANT: PLEASE DO NOT Rely on this for defined workloads such as in your application suite.

11 저장 프로시저 어떻게 작업 하는가? 서버에 컴파일된 구문 저장 객체 관리 계속적 지원 어플리케이션에 의한 파라메터 명시
케시에 있는 컴파일된 계획 실행 WITH RECOMPILE 옵션으로 재 컴파일 저장 프로시저로 동적 생성 구문 수행 Sp_executesql, EXEC Lets talk about stored procedures - As a general rule, All well-designed SQL Server applications should try to use stored procedures. Transact-SQL statements compiled into stored procedures can save a significant amount of processing at execution time. A stored Procedure is a group of SQL statements compiled into a single execution plan They return data with result sets, or output parameters which return data (integer or character value), or a cursor variable. SPs assist in a single implementation of logic across your application – they are designed and coded once – The calling application does not need to transmit the SQL statements to the server for the stored procedure – they already exist there (once created) – only the values for the parameters need to be sent. So this the network can be used more efficiently There is a WITH RECOMPILE option that indicates to SQL to not cache the plan and recompile at runtime. This is to be used only when you have atypical results that will vary resultsets significantly and can have negative performance implications If you will be generating dynamic SQL within a SP, you have two choices: - Use an exec string if you are change the SQL completely – for example table names, and the columns to the acted on - Use execute_Sql if you are just changing the parameter values, or if you are changing the form that other users could benefit from. If you are constructing SQL, and then calling it in a loop, -the exec will require a compile per loop iteration while the executesql would not. -on the other hand if plan choices would be dramatically different between invocations, an exec string would not reuse the plan and could be better. In other words, you need to do some performance analysis.

12 저장 프로시저 장점 데이터에 대한 비즈니스 로직의 은익화 수행 속도 재사용성 네트웍 트래픽의 감소
RPC 수행을 통한 구문 파싱과 파라메터 프로세싱 작업을 안함 사용자 정의 함수(UDFs)도 비슷한 장점이 제공됨 Stored procedures help in achieving a consistent implementation of business rules across your application suite. The SQL logic needed to perform a commonly performed task can be designed, coded and tested once, with the general applications just requesting execution of the stored proc. Another general rule to help on scalability is to have the business logic closest to the data when there is business logic that is critical to scalability – I.e. to generate the next order number etc. – this could be done effectively on the server reducing n/w round-trips and contention – this could be critical to removing bottlenecks to scalability In addition, many business tasks are implemented as a series of statement which could have conditional logic based on the results of one of the earlier queries – if the statements and conditional logic are written into the stored proc, it becomes one execution on the server – I.e. results do not need to be sent back to the client to apply the conditional logic. Please note that even standard Transact-SQL statements with no business logic component gain a performance advantage when packaged as stored procedures with parameters. We have discussed the UDFs in other presentations this week – UDF and UDTs return result sets and can help provide similar benefits from this standpoint

13 저장 프로시저 잘못된 저장 프로시저 호출 방법 값으로 직접 호출하지 마라… //나쁜 수행 방법이다.
//호출 할 때 마다 보내어진 값 ‘myval’에 대해 컴파일 한다. //RPC event 대신에 SQLBatch로 수행되어 진다. SQLExecDirect(hStmt,“execute mysp‘myval’”, SQL_NTS); //최적화된 상태는 아니다. //호출할 때마다 값에 대해 컴파일하여야 하기 때문에 SQLExecDirect(hStmt,“{ CALL mysp(‘myval’)}”, SQL_NTS); The Microsoft® SQL Server™ ODBC driver supports both the ODBC CALL escape sequence and the Transact-SQL EXECUTE statement for executing stored procedures; the ODBC CALL escape sequence is the preferred method. Using ODBC syntax enables an application to retrieve the return codes of stored procedures and the SQL Server ODBC driver is also optimized to use a protocol originally developed for sending remote procedure (RPC) calls between SQL Servers. This RPC protocol increases performance by eliminating much of the parameter processing and statement parsing done on the server. ODBC example, the way to do this in OLEDB is….

14 저장 프로시저 SP를 효과적으로 호출하는 방법
파라메터를 이용한 호출 구문 // Bind parameters char szParam[32]; SQLBindParameter(hStmt,…,szParam); // Set parameters strcpy(&szParam[0], “myval”); // Execute the stored procedure SQLExecDirect(hStmt, “{ CALL mysp(?) }”, SQL_NTS); //Even better on SQL Server 2000 SQLPrepare ( hStmt, “{ CALL mysp(?) }”, SQL_NTS); SQLExecute ( hStmt ); 다음 호출시 케시에 있는 플랜을 사용 When a SQL statement calls a stored procedure using the ODBC CALL escape clause, the Microsoft® SQL Server™ driver sends the procedure to SQL Server using the remote stored procedure call (RPC) mechanism. RPC requests bypass much of the statement parsing and parameter processing in SQL Server and are faster than using the Transact-SQL EXECUTE statement. To run a procedure as an RPC Construct a SQL statement that uses the ODBC CALL escape sequence. The statement uses parameter markers for each input, input/output, and output parameter, and for the procedure return value (if any): {? = CALL procname (?,?)} Call SQLBindParameter for each input, input/output, and output parameter, and for the procedure return value (if any). Execute the statement with SQLExecDirect.

15 ExecuteSQL 어떻게 작업되는가? 어플리케이션에 의해 생성되며 지속적 객체 관리가 안됨
Example: Sp_ExecuteSQL 'insert T1 values ', float',1 Sp_ExecuteSQL 'insert T1 values ', float', 3 Sp_ExecuteSQL 'insert T1 values ', float', 1 ODBC SQLExecDirect 또는 OLEDB ICommandWithParameters 로 구현 가능 You can think of sqlExecSQL as halfway halfway between adhoc caching and SPs. They are very similar to stored procedures …. But are created on the fly by the application And there is not a requirement of persistent object management as of SPs. So using the example from before - Repeated calls with the same batch_text will use the cached plan, with the new parameter values specified. So the same cached plan will be used in all cases. For ISVs that SQL worked with in the SQL7 times, we indicated that you should use this method when the application was not sure whether multiple copies of this statement would be used on the connection …. It was one round trip to the server to get the statement ready This is exposed in ODBC as SQLExecDirect and in OLE-DB with ICommandWithParameters.

16 Prepare / Execute 어떻게 작업하는가?
어플리케션에 의해 생성 파라메터를 Question marks(?)와 문자열로 쿼리를 수행한다. 반복적 수행에 대해 효과적인 지원 UnPrepare가 발생할 때 초기화됨 ODBC, OLEDB, or DB-Library의 ICommandPrepare에 의해 지원됨. DELETE FROM AUTHORS WHERE au_fname = ? AND au_lname = ? Prepare/Execute is another method that we encourage application developers to use to make effective use of the plan cache. In many cases the application understands general usage of the statements by the user and can help use the mechanism that helps scale the best. Consider an application using one connection that is repeatedly calling the same query, sending the query down the wire each time Prepare/Execute Is like SP_EXECUTESQL in that parameters to the batch are identified by the application and the technique is purposely used, but: - It does not require the full text of the batch to be sent each execution. - Rather, the batch is sent one at prepare time to the database server and a handle is returned - The "handle" is then used repeatedly on an execute call to invoke that batch (at execute time) along with the parameters values for the particular execution ODBC and OLE-DB expose this functionality via SQLPrepare/SQLExecute and ICommandPrepare. This mechanism is also usable via ODBC/OLE-DB when cursors are involved. Trade-offs include: - handle can be used on only one one connection, and if the query is being called only once – there will be extra round-trips without the benefit.

17 부적절한 실행 계획의 공유 케시의 수행 계획을 사용하고 싶지 않을 때 최적화된 수행 계획은 선택 파라메터에 의해 결정되기 때문
예제 : Select * from T where c>=5 and c<=10 (index lookup) Select * from T where c>=5 and c<=100 (table scan) 단일 실행 계획으로 두 구문에 대해 최적화된 실행 계획을 가질 수 없다. I want talk about an issue before getting into some good news for SQL Server INAPPROPRIATE SHARING For all of the caching mechanisms, re-using a cached plan avoids re-compilation & optimization. This saves compilation time, but means the same plan is used, regardless of the particular parameter value(s) passed in. If the optimal plan for a given parameter value is not the same as the cached plan, the optimal execution time will not be achieved. This is why the server is "conservative" about auto-parameterization. When using sp_executesql, sp_prepare/sp_execute and stored procedures, the application takes responsibility for determining what should be parameterized. Only parameterize constants whose range of values does not drastically affect the optimization choices made. The Graphical Query Analyzer can show what optimization choices are made. Consider the following case. For example, suppose table T has a column c with a non-clustered index on it, range of values The queries: Q#1: select * from T where c >= 5 and c <= 10 Q#2: select * from T where c >= 5 and c <= 95 You do not want to submit this as a executesql or prepare/exeute with 2 parameters to indicate the start and end of the ranges. The optimial plan for Q#1 (index lookup) is not the same as Q#2(table scan) When compiling a plan, SQL Server uses the current values of the parameters as the 'default' values around which to select a plan. So in the example the cached plan would be an index lookup and would not be appropriate when called with values of parm1 and parm2 for which table scan is faster. A technique is available that would allow an application to still utilize caching mechanisms if it could distinguish between the parameter values for which table scan was appropriate and and those for which index scan was appropriate. In the case of prepare/execute, you would re-prepare …. In the case of executeSQL, you could call sp_executesql with a comment in the query that indicates the index and the tablescan case, and with different initial values, would generate separate plans which the application could call appropriately, sp_executesql ('select * from T where c AND c --the index lookup int',5,10) sp_executesql ('select * from T where c AND c --the tablescan int',5,95) sp_executesql ('select * from T where c AND c --the index lookup int',4,11) sp_executesql ('select * from T where c AND c --the tablescan int',4,96) the comment following the query means separate plans will be cached

18 SQL 7.0 수행 속도의 핵심 ExecDirect 대 Prepare/Execute
대부분의 많은 어플리케이션들은 독립적인 드라이버 레이어로 구현된다 어플리케이션 로직으로 독립된 데이터베이스 특별한 목적을 위한 프레임웍 Passing hints 사용자 사용의 예측 Application 서버 N+2 costing With SQL7 we talked to many application developers discussing the many caching mechanisms that allow sharing of plans within a connection and for many users. The question was when to use prepare/execute and ExecDirect However, many application suites use a database driver layer for a variety of reasons - to use more that one DBMS - to isolate database specifics from all the application layers etc … - issues was how would you identify cases on when to use prepare/execute instead of execsql - would you even be able to pass hints from the application, - would you special case based on call users profile Basically, we were asking you to predict usage by user The problem got larger when talking about the application server models that some folks implemented with connection pooling etc. Our advise was Prepare/execute was optimal for repeated use of the same query/batch within a connection – but this uses N+2 round-trips for N executions (prepare, execute, execute, execute, unprepare). In particular cases this is straight forward (dozens of repeats) – use prepare/execute – if once – use ExecDirect The cross over point depended on your circumstances – and was difficult to determine for some ISVs Well – we listed

19 적은 Round-Trips SQL Server 2000 개선 부분
Prepare/Execute model: 모든 파라메터의 타입을 명시할 수 있음 Prepare와 Execute 간의 요청 사항 없음 N 번의 라운드 트립은 N 번의 수행을 이야기 한다. 권고 사항 : 항상 Prepare/Execute 사용하자! In SQL Server 2000, we improved the the caching mechanisms: We greatly optimized the ODBC and OLE/DB driver and driver managers to reduce the number of round-trips when using prepare/execute under the following conditions: If the types of all parameters are specified before the prepare, and no result-set meta-data is requested between prepare and execute, (I.e. SQLDescribeCol or SQLDescribeParm in ODBC) What is happening is that the driver-manger is caching the statement on the prepare – and not RPC’ing to the server … This will be passed on the first execute … where the prepare is done, a handle assigned and the first execution completed. The handle is passed back and can be used by the second and subsequent execution. When all the executions are done, the application issues an un-prepare – again the driver-manager on the client or the app server will not do a round trip but cache the handle. On a subsequent prepare, the handle (not-Null) will be passed in and SQL server will unprepare the first statement/batch and then prepare the second. SO now for instance in in ODBC, the sequence: {SQLPrepare,SQLExecute,SQLExecute,release the statement} results in 2 round-trips. This is the same number of round-trips as {SQLExecDirect,SQLExecDirect}. The number of round-trips for N executions is now N. This is all automatic – your application does not have to change if you are using prepare/execute – you will get the reduced round trips with SQL Server 2000. This has show great benefit when working with ISV benchmarks in the labs and ones that we publish in conjunction with the W2K launch – but that is the benchmark world consider the even more impressive savings that you can see with reduced round-trip in a real-world WAN environment. You Now do not have to make choice that was difficult for some of you between prepare/execute and execsql – Use prepare/execute instead of ExecuteSQL on SQL Server2000.

20 Prepare/Execute Round-Trips SQL 서버 7.0에서
User Code UnPrepare UnPrepare Prepare Execute Execute Prepare Execute Execute 7.0 Client Prepare Handle Execute Response Execute Response UnPrepare Response Prepare Handle Execute Response Execute Response UnPrepare Response In SQL Server 2000, we improved the the caching mechanisms: We greatly optimized the ODBC and OLE/DB driver and driver managers to reduce the number of round-trips when using prepare/execute under the following conditions: If the types of all parameters are specified before the prepare, and no result-set meta-data is requested between prepare and execute, (I.e. SQLDescribeCol or SQLDescribeParm in ODBC) What is happening is that the driver-manger is caching the statement on the prepare – and not RPC’ing to the server … This will be passed on the first execute … where the prepare is done, a handle assigned and the first execution completed. The handle is passed back and can be used by the second and subsequent execution. When all the executions are done, the application issues an un-prepare – again the driver-manager on the client or the app server will not do a round trip but cache the handle. On a subsequent prepare, the handle (not-Null) will be passed in and SQL server will unprepare the first statement/batch and then prepare the second. SO now for instance in in ODBC, the sequence: {SQLPrepare,SQLExecute,SQLExecute,release the statement} results in 2 round-trips. This is the same number of round-trips as {SQLExecDirect,SQLExecDirect}. The number of round-trips for N executions is now N. This is all automatic – your application does not have to change if you are using prepare/execute – you will get the reduced round trips with SQL Server 2000. This has show great benefit when working with ISV benchmarks in the labs and ones that we publish in conjunction with the W2K launch – but that is the benchmark world consider the even more impressive savings that you can see with reduced round-trip in a real-world WAN environment. You Now do not have to make choice that was difficult for some of you between prepare/execute and execsql – Use prepare/execute instead of ExecuteSQL on SQL Server2000. SQL Server 7.0

21 Prepare/Execute Round-Trips SQL 서버 2000에서
User Code UnPrepare Prepare Execute Execute UnPrepare Prepare Execute Execute 2000 Client Prepare+Execute Handle +Response Execute Response UnPrep+Prep+Exec NewHandle+Response Execute Response In SQL Server 2000, we improved the the caching mechanisms: We greatly optimized the ODBC and OLE/DB driver and driver managers to reduce the number of round-trips when using prepare/execute under the following conditions: If the types of all parameters are specified before the prepare, and no result-set meta-data is requested between prepare and execute, (I.e. SQLDescribeCol or SQLDescribeParm in ODBC) What is happening is that the driver-manger is caching the statement on the prepare – and not RPC’ing to the server … This will be passed on the first execute … where the prepare is done, a handle assigned and the first execution completed. The handle is passed back and can be used by the second and subsequent execution. When all the executions are done, the application issues an un-prepare – again the driver-manager on the client or the app server will not do a round trip but cache the handle. On a subsequent prepare, the handle (not-Null) will be passed in and SQL server will unprepare the first statement/batch and then prepare the second. SO now for instance in in ODBC, the sequence: {SQLPrepare,SQLExecute,SQLExecute,release the statement} results in 2 round-trips. This is the same number of round-trips as {SQLExecDirect,SQLExecDirect}. The number of round-trips for N executions is now N. This is all automatic – your application does not have to change if you are using prepare/execute – you will get the reduced round trips with SQL Server 2000. This has show great benefit when working with ISV benchmarks in the labs and ones that we publish in conjunction with the W2K launch – but that is the benchmark world consider the even more impressive savings that you can see with reduced round-trip in a real-world WAN environment. You Now do not have to make choice that was difficult for some of you between prepare/execute and execsql – Use prepare/execute instead of ExecuteSQL on SQL Server2000. SQL Server 2000

22 Meta-Data 감소 SQL 서버 2000에서 개선
Selects: 각 컬럼을 위한 meta-data 클라이언트 사이드에 Meta-data를 케싱 (prepare/execute의 사용으로) meta-data와 파라메터에 의한 처리 많은 컬럼의 테이블에 대한 비용 감축(30%) SQL2000 클라이언트에 의한 최적화 단지 SQL 서버의 데이터와 데이터 길이만 조회 Although critical, in many cases column meta-data can be considered overhead We look at everything that affects performance and scalability – we took a long look at our use of meta data and found that we could optimize it for SQL2000 without impacting functionality . Many ISVs do a large number of selects that result in singleton or small result sets – if you are bringing back many or all the columns, SQL needs to bring back the meta-data that describes that data-type for each column. The cost of sending this meta-data could be large (10%+ of the traffic of a moderate sized table – and much more for very wide tables). We optimized this by caching meta-data on the client side when using the prepare/execute model which I just recommended that you use. On subsequent executes, we will not re-send the metadata if the schema has not changed – which is quite likely This is all automatic when you use prepare/execute in SQL2000 – Some applications have table with many columns. Inserts and updates specify all these columns and processing the parameter processing can be expensive (upto 30% of the total cost for tables with large numbers of columns). The fact is that the meta-data describing the meta-data does not change with multiple executions on the same connection. When using the prepare/execute model a object is constructed for transferring parameter data and metadata between the TDS data stream and procedure parm table. This is cached, and on subsequent execution, if the client driver indicated that the parm metadata is unchanged, the cached structure is used and only the data and length of data is read. We are saving the parameter processing on subsequent executions and the savings can be significant. A: result-set meta data … not resent on TDS stream …. Great with lots of columns --- small number of rows …. B: SQL OLE/DB only (3 in Sada’s notes) meta data to describe column defns – On server side – don’t process – flag for metadata has not changed. (need flag in case schema changed) no need to check and process the meta data … (???? Reuse cmd obj – G2)

23 권고 사항 SQL 서버 2000에서 가능한 저장 프로시저를 사용하라. Prepare/Execute를 사용하라.
(SQLExecute 대신) 가능한 파라메터화 하라 파라메터의 변동 폭이 큰 경우는 주의할 필요가 있다. 가능하다면 어플리케이션에서 파라메터의 데이터 형을 명시하라. 공통적인 룰을 관찰하고 적용하라. 툴을 사용하여 compiles/recompiles에 대한 통계를 관측하여 적용하라. With SQL Server 2000, for application developers to build optimally performing and scalable application we have the following recommendations: As much as possible use stored procedures, and keep business logic close to the server. It is really good to cut down on the round trips and save concurrency – Especially for things like generating the next order number, do it on the server – there really is not a reason to come back to the client to apply the logic User prepare/execute – there is no need to calculate the trade off between prepare/execute and execdirect – you will get all the benefits of prepare/execute without the round-trip impact that was there in SQL7. This is whether you are going to be sharing the connection or cross connection. Parameterize – as the application developer, you know what are truly parameters and you should really control this – it is not difficult Look out in parameterization – if the range of values are changing drastically, you need to make sure that you do not get suboptimal plans Sharing - To maximize the performance of the caching mechanisms, follow the sharing rules: - Insure all users execute in the same environment - Don't change SET or database settings in the middle of an application or connection – in most cases it is not needed - Insure batches/procedures don't require implicit resolution except where absolutely necessary and share appropriately: -Do not parameterize constants whose range of values drastically affects the optimization choices made. Final Message - When you look at overall performance and scaling of an application, the goal really should be no ongoing compilations once the system has ramped up – there is not added benefit for compiling - I.e. total reuse once warmed up

24 커서를 사용하는 이유? 데이터베이스 드라이버와 함께 어플리게이션을 구현할 수 있음
행 작업에 대해 스크롤(scroll)과 수정(update) 가능 하나의 커넥션에 여러 반복적 구문 수행 가능 일부 행에 대한 부분 처리를 위해 어플리케이션에서 커서 사용을 필요로 하는 경우 There is a second area of application development that greatly affects performance and scalability is cursors So why would you use cursors – a few: A major reason that we have seen among the ISV that we have worked closely with is that they support more that 1 dbms - they have to be database independent – and a common way seems to involve isolating the main application code from a database driver layer. - since they support many dbmses – they tend to make use of cusors. Another reason is to have cursors provide support for scrolling with update within a rowset – and do not want to implement this functionality on the client You might also want to use multiple active statements on the connection In addition, there might be a possibility of consuming a smaller subset that was requested on the query.

25 효과 적인 커서의 사용 커서 타입의 선택에 따라 수행 성능의 차이가 커질 수 있음
요구 수행할 수 있는 최소 비용이 드는 커서 타입을 사용 커서 기본 옵션이나 Fast Forward Only를 사용 다른 기능을 원한다면 다른 커서 타입을 고려한다. Server/Network 자원 사용에 대한 고려를 한다. 최소 비용이 드는 트랜젝션을 고려한다. SQL Server is naturally set oriented – in other words the preference is to return a set of rows from a given select. And it would be a mistake to turn this into ISAM row based behavior. When you look at cursors you can talk about server side cursors and client side cursors. The Server side cursors are maintained by SQL server while client side are provided by the interface like the ODBC client side cursor library. Client side cursors are more generic, work against just about any provider and tend to do much more round-trips, while obviously server side cursors are tightly integrated with SQL Server. With regards to high performance applications, you need efficient optimized conversation between the client and server – this was done for the ODBC and OLE/DB drivers for SQL Server. I will be talking about server side cursors. I am talking about cursors in a rather generic form here, considering the default answer set (or sometime called firehose) as a pseudo-cursor. As far as choosing to access your data on SQL Server you would want consider your lower cost options (in terms of resources, network and round-trips). These are default result set and Fast Forward Only cursor – These two should satisfy 90+% of your requirements. If you need more capability than this, you will want to consider the more ‘rich’ cursor model – dynamic, keyset and static. But the trade-off will be in terms of server resources and performance. From a performance and scalability standpoint, it is very important to consider the impact on server and network resources by your choice of cursor. From a network round-trip standpoint, you will want to optimize the rowset size You should also note that the locking behavior of cursors is based on the interaction between concurrency attributes and the transaction isolation level set by the client. Read committed, read uncommitted – and then repeatable reads or serializable - share lock on each row as read into cursor, but if the cursor is opened within a transaction, it is held until the end of the transaction.

26 기본 결과 셋 기본 적인 모델은 커넥션에 대해 단일 SQL 구문이다.
결과 셋을 모두 사용하게 최적화된 결과 셋을 조회하여야 한다. 잇점: 적은 서버 자원의 사용 불필요한 자료 요구의 제거 핵심: 결과 셋을 사용하는 동안 커넥션 은 쉬지 않고 움직인다. The first low-cost, efficient method that you should consider is the default row-set or firehose cursor, and not really a formal server cursor. You want to consider this option first as this is the best and most efficient way of returning rows from SQL Server. SQL compiles and then executes the statement or batch on behalf of the client machine. SQL server then begins putting the rows of the result set into network packets (filling them best as possible) and sending them down the wire to the client. These packets are cached in the n/w buffers of the client. The driver (ODBC or OLE/DB) pulls the rows and transfers to the client application. The client will retrieve these results in a forward only direction and are read-only It is actually called the default result set, because you get this with the default set of attributes – forward-only, read-only with a rowset of 1. The data is transferred to the client with the n/w buffers, but fetched as the app requests one row at a time. Note that client cannot do another statement on this connection until all of the result set has been consumed, or a cancel has been issued. It is definitely recommended when you will be consuming the full result set, and especially small result sets Default result sets are the most effective way to transmit results to the client. The only packet sent from the client to the server is the original one with the statement to execute. The client does not have to make a request to get more data. SQL puts the most rows that it can into the buffer and sends it down while the client can still cached n/w buffers. The server does not need to stage data on the server, and it minimized overhead on the server, including only one lock on the next row which has not been sent. The major consideration for your application is that you can only have one active statement at a time on the connection. Alazel: Firehose is optimal if there is just 1 query …. Locks on first row of stuff not sent … could be many buffers sent … Connection is in use for the whole time …. Usually the most efficient method in terms of server resources, n/w round trip.

27 기본 결과 셋 예 … Client SQL Server Cursor Open Get Next Rows
Result Set Packet Result Set Packet Result Set Packet In SQL Server 2000, we improved the the caching mechanisms: We greatly optimized the ODBC and OLE/DB driver and driver managers to reduce the number of round-trips when using prepare/execute under the following conditions: If the types of all parameters are specified before the prepare, and no result-set meta-data is requested between prepare and execute, (I.e. SQLDescribeCol or SQLDescribeParm in ODBC) What is happening is that the driver-manger is caching the statement on the prepare – and not RPC’ing to the server … This will be passed on the first execute … where the prepare is done, a handle assigned and the first execution completed. The handle is passed back and can be used by the second and subsequent execution. When all the executions are done, the application issues an un-prepare – again the driver-manager on the client or the app server will not do a round trip but cache the handle. On a subsequent prepare, the handle (not-Null) will be passed in and SQL server will unprepare the first statement/batch and then prepare the second. SO now for instance in in ODBC, the sequence: {SQLPrepare,SQLExecute,SQLExecute,release the statement} results in 2 round-trips. This is the same number of round-trips as {SQLExecDirect,SQLExecDirect}. The number of round-trips for N executions is now N. This is all automatic – your application does not have to change if you are using prepare/execute – you will get the reduced round trips with SQL Server 2000. This has show great benefit when working with ISV benchmarks in the labs and ones that we publish in conjunction with the W2K launch – but that is the benchmark world consider the even more impressive savings that you can see with reduced round-trip in a real-world WAN environment. You Now do not have to make choice that was difficult for some of you between prepare/execute and execsql – Use prepare/execute instead of ExecuteSQL on SQL Server2000. SQL Server

28 Fast Forward-Only 커서 forward-only와 read-only를 조합한 서버 커넥션이 많은 경우 유리
네트웍이 약한 기반에서 유리 기초 테이블에 직접 작업 Fetch next 만 지원 수정된 데이터에 대한 반영 됨 ODBC에서 AutoFetch를 활성화 하여 놓으면, AutoClose 역시 자동으로 작동됨 The first real Server cursor is FastForwardOnly cursors, which is the other lower cost model that we would like you to consider first. SQL Server has optimized forward-only, read-only cursors in this case. The major advantage that FFO cursors have over the default result set is that they significantly reduce the connection busy. The connection is busy and tied only between the client request to fetch next and until the server data is sent. After that, to the next fetch, the connection can be used for other uses. Think of FFO as an optimized thin layer over the query, unlike the richer cursor models. The cursor operates directly over the base tables, And obviously supports only fetch next. If data in the result change is committed, before the fetchnext buffer has been processed, the result will be seen. This is a good time to talk about Auto-Fetch: Auto-Fetch is an an option where the first rows or row-sets are retrieved on the open. It saves a network round-trip on the first fetch. This is available for all cursor models but requires the application to set the option. If Auto-fetch is on, Auto-Close is also on. Auto-close means that the cursor is closed on the last fetch which exhausts the result set You save an additional n/w round-trip. So for example, if you end up having a small result set which is smaller than the rowset specified in the option, the open would fetch rows because of the autofetch option, get the rows, realized it was the end of the result set and close the cursor because of the auto-close option. This would reduce the round trips in this case from 3 to 1. In terms of performance: There will be more n/w buffers than firehose. First, after the autofetch, fetch requests from the client to the server will be required. In addition, the request specified rowset size will be returned with each fetch request – and this might not necessarily be the most efficient packing of network buffers as in the firehose case. In most cases, FFO is more expensive that the Default Result Set (about 10-40% in some tests), but definitely a low-cost cursor that reduces server resources and n/w round-trips, when compared to richer cursors. Alazel: connection only tied up between the client request –to- server data sent … after that to the next fetch request, the connection is not busy. More n/w packets --- request required Can be 10-50% overhead over the the default.

29 Fast Forward Only Example
Client Cursor Open Get Next Rows Result Set Packet Get Next Rows Result Set Packet Get Next Rows Result Set Packet In SQL Server 2000, we improved the the caching mechanisms: We greatly optimized the ODBC and OLE/DB driver and driver managers to reduce the number of round-trips when using prepare/execute under the following conditions: If the types of all parameters are specified before the prepare, and no result-set meta-data is requested between prepare and execute, (I.e. SQLDescribeCol or SQLDescribeParm in ODBC) What is happening is that the driver-manger is caching the statement on the prepare – and not RPC’ing to the server … This will be passed on the first execute … where the prepare is done, a handle assigned and the first execution completed. The handle is passed back and can be used by the second and subsequent execution. When all the executions are done, the application issues an un-prepare – again the driver-manager on the client or the app server will not do a round trip but cache the handle. On a subsequent prepare, the handle (not-Null) will be passed in and SQL server will unprepare the first statement/batch and then prepare the second. SO now for instance in in ODBC, the sequence: {SQLPrepare,SQLExecute,SQLExecute,release the statement} results in 2 round-trips. This is the same number of round-trips as {SQLExecDirect,SQLExecDirect}. The number of round-trips for N executions is now N. This is all automatic – your application does not have to change if you are using prepare/execute – you will get the reduced round trips with SQL Server 2000. This has show great benefit when working with ISV benchmarks in the labs and ones that we publish in conjunction with the W2K launch – but that is the benchmark world consider the even more impressive savings that you can see with reduced round-trip in a real-world WAN environment. You Now do not have to make choice that was difficult for some of you between prepare/execute and execsql – Use prepare/execute instead of ExecuteSQL on SQL Server2000. SQL Server

30 정적(Static) 커서 커서 오픈 시 스냅샷(Snapshot) 형태로 TempDB에 임시 테이블을 생성하여 사용
읽기 전용 – 기초 테이블 수정 불가 모든 스크롤(scroll) 옵션 가능 데이터의 동적 반영이 안됨 A static cursor is implemented with a snapshot of the resultset data – which is stored in a temp table at cursor open on the server. It is the complete result set and always displays the result set as it was when the cursor was opened. The cursor will not reflect any changes made in the database that affect either the membership of the result set or changes to the values of the columns that were in the snapshot. It will not reflect any new rows – even if they match the search conditions of the cursor select statement. This is read-only – the underlying tables cannot be updated … as you are working with a snapshot All the scrolling options are available – and there is obviously not a benefit with Forward-only Implications: Because it is snapped-shotted in tempdb – the rowsize of the request result set, cannot exceed the rowsize of SQL Server. There can be significant impact on server resources – creating, populating, and cleaning up the materialized answer set in temporary tables on the server. There is also the cost of retrieving the row to send to the client. This is very important – in initial scaling tests with some of our partners, we have seen the allocation, population and cleaning up of the temp resources temper the scaling performance of the database server. This tempered the number of concurrent users – it turned out that most of the interaction could be done with lower cost models, which improved drastically the number of concurrent users.

31 정적(Static) 커서 동작원리 … Client SQL Server Base Tables Query TempTable
Cursor Open Get Next Rows Result Set Packet Get Next Rows Result Set Packet Get Next Rows Result Set Packet In SQL Server 2000, we improved the the caching mechanisms: We greatly optimized the ODBC and OLE/DB driver and driver managers to reduce the number of round-trips when using prepare/execute under the following conditions: If the types of all parameters are specified before the prepare, and no result-set meta-data is requested between prepare and execute, (I.e. SQLDescribeCol or SQLDescribeParm in ODBC) What is happening is that the driver-manger is caching the statement on the prepare – and not RPC’ing to the server … This will be passed on the first execute … where the prepare is done, a handle assigned and the first execution completed. The handle is passed back and can be used by the second and subsequent execution. When all the executions are done, the application issues an un-prepare – again the driver-manager on the client or the app server will not do a round trip but cache the handle. On a subsequent prepare, the handle (not-Null) will be passed in and SQL server will unprepare the first statement/batch and then prepare the second. SO now for instance in in ODBC, the sequence: {SQLPrepare,SQLExecute,SQLExecute,release the statement} results in 2 round-trips. This is the same number of round-trips as {SQLExecDirect,SQLExecDirect}. The number of round-trips for N executions is now N. This is all automatic – your application does not have to change if you are using prepare/execute – you will get the reduced round trips with SQL Server 2000. This has show great benefit when working with ISV benchmarks in the labs and ones that we publish in conjunction with the W2K launch – but that is the benchmark world consider the even more impressive savings that you can see with reduced round-trip in a real-world WAN environment. You Now do not have to make choice that was difficult for some of you between prepare/execute and execsql – Use prepare/execute instead of ExecuteSQL on SQL Server2000. Base Tables TempTable Query SQL Server

32 키셋(Keyset) 커서 커서 오픈 시 키셋에 대해 TempDB에 임시 테이블로 저장하여 사용
커서를 오픈하면 키셋의 구성요소가 고정됨 모든 스크롤(scroll) 옵션 가능 SELECT 관계된 모든 테이블에 unique index가 필요 인덱스 컬럼 이외의 데이터는 동적으로 수정된 자료 조회 가능 새로운 데이터의 추가는 조회 불가능 기존 데이터의 삭제는 에러 = -2인지를 확인 WHERE CURRENT OF구문으로 인덱스 컬럼의 변경에 대해서는 조회 가능 Using a keyset cursor will create a keyset – in other words the index keys of the answer rowset materialized in a temp table The membership and order of rows in the result set are fixed at cursor-open time, but value changes made by the cursor owner and committed changes made by other users are visible. If a change disqualifies a row for membership or affects the order of a row, the row does not disappear or move unless the cursor is closed and reopened. Inserted phantom rows data does not appear, but changes to existing data do appear as the rows are fetched. In a keyset-driven cursor, all keys for the result set are kept locally (which is one reason a unique index is required). Given the results of n rows, the keyset contains the same n rows in the result set. The fetch buffer contains 10 rows by default, and moves forward through the keysets as each FETCH statement is executed. Although values can change between fetches, rows do not move around if the changes affect ORDER BY columns, and they do not disappear if they no longer satisfy the WHERE clause. In addition, because of the fixed membership, you can fetch to an absolute position. There is a requirement is to have a unique index on every table in the select The performance implication is that the keyset (index keys) making the resultset are materialized in temp db. This needs to be created, and are then fetched and matched with the other column data from the base tables.

33 Keyset Cursors Example
Client Cursor Open Get Next Rows Result Set Packet Get Next Rows Result Set Packet Get Next Rows Result Set Packet In SQL Server 2000, we improved the the caching mechanisms: We greatly optimized the ODBC and OLE/DB driver and driver managers to reduce the number of round-trips when using prepare/execute under the following conditions: If the types of all parameters are specified before the prepare, and no result-set meta-data is requested between prepare and execute, (I.e. SQLDescribeCol or SQLDescribeParm in ODBC) What is happening is that the driver-manger is caching the statement on the prepare – and not RPC’ing to the server … This will be passed on the first execute … where the prepare is done, a handle assigned and the first execution completed. The handle is passed back and can be used by the second and subsequent execution. When all the executions are done, the application issues an un-prepare – again the driver-manager on the client or the app server will not do a round trip but cache the handle. On a subsequent prepare, the handle (not-Null) will be passed in and SQL server will unprepare the first statement/batch and then prepare the second. SO now for instance in in ODBC, the sequence: {SQLPrepare,SQLExecute,SQLExecute,release the statement} results in 2 round-trips. This is the same number of round-trips as {SQLExecDirect,SQLExecDirect}. The number of round-trips for N executions is now N. This is all automatic – your application does not have to change if you are using prepare/execute – you will get the reduced round trips with SQL Server 2000. This has show great benefit when working with ISV benchmarks in the labs and ones that we publish in conjunction with the W2K launch – but that is the benchmark world consider the even more impressive savings that you can see with reduced round-trip in a real-world WAN environment. You Now do not have to make choice that was difficult for some of you between prepare/execute and execsql – Use prepare/execute instead of ExecuteSQL on SQL Server2000. Base Tables TempTable Keys Base Tables Query SQL Server

34 Dynamic Cursors 기초 테이블을 직접 조작
모든 스크롤 옵션 가능 절대(absolute position)위치 변경은 지원 안됨 스크롤 할 때 마다 변경된 모든 데이터 조회 가능 Join으로 열린 커서에 대한 제약이 따름 (INSERT,UPDATE) 성능 저하의 우려가 있음 Dynamic cursors operate directly on the base tables Think of dynamic cursors as continually applying the select criteria as fetches are processed allowing for new or fewer rows. So column values can change as a result of inserts, updates, and membership of the rowset can change – This is all dependent on the concurrency options specified on the cursor. This happens whether it was a result of this clients actions or from other users. Because the membership can change, fetch absolute is not allowed, but fetch relative is …. There are limited join techniques on dynamic cursors and you must understand the circumstance for a downgrade of cursor (or implicit cursor conversion) that I will discuss next. The performance implications is that each fetch on a dynamic cursor, will requery the tables involved in the answer set

35 묵시적인 Cursor 형 변환 서버에 필요 결과 셋을 요구할 때
원래의 질의에 영향을 받아 ORDER BY (index에 포함되지 않은 컬럼으로) TOP, GROUP BY, UNION, DISTINCT …. 대부분은 static으로 변환 형 변환 룰에 의한 커서형 변환 권고 사항: 커서 형 변환을 확인하기 위해 SQL_SUCCESS_WITH_INFO를 확인 Cursor Downgrade or sometimes called implicit cursor conversion generally occur when we need to further materialize the answer set on the server in tempdb. Depending on original cursor request – dynamic, keyset and fast forward only, there can be a down grade from the requested cursor type… A common case is the query requests an order by which is not covered by existing indexes. In this case, a internal worktable is required to provide proper sorting order, and a forward only or dynamic cursor can be downgrade to keyset. Other cases include: - cursors referencing a view with a top n condition - if the select list contains an aggregate like group by, distinct, having, - forward only, keyset and dynamic all downgrade to static - if a keyset query references at least one table without an unique index, it will be down graded to static. These are in the SQL Server documentation for each release – please keep in mind that behavior can change with enhancements to new releases of SQL. The most important message that I would like to convey is to test – in development builds, put out an warning message so that you can track down whether this is acceptable behavior for your case. The return code will be a SQL_SUCCESS_WITH_INFO.

36 Static 대 Keyset Static Keyset Asynchronous 정도 설정 전체 구성 요소 셋을 만듬
연속적인 페치 시 가장 저렴한 비용 Keyset 키 구성 요소 셋을 만듬 페치 시 인덱스 외의 컬럼을 페치 Static 보단 저렴한 비용 Asynchronous 정도 설정 Sp_configure ‘cursor threshold’ n What really is the difference in performance between keyset and dynamic cursors The static cursor will materialize the entire answer set to disk While the keyset cursor will have the rids or keys materialized. So opening of a keyset cursor would be generally be faster … Fetching rows on static cursors are relatively straight forward – getting them from the snapshot image. This will be the cheapest subsequent fetch Fetching from keyset is the next cheapest fetch, requiring gathering non-index key columns from data pages. Dynamic fetches are generally the most expensive fetches – as the original select condition might have to be reapplied. Another rule of thumb is regarding the number of tables referenced in the result set Dynamic cursors are generally fast when there is 1 table in the result set Keyset and statiic are faster when joins are required. Please note that you can asynchronously populate the answer set for keyset and static using the cursor threshold configuration parameter – in the meantime result can be returned. If you set cursor threshold to -1, the answerset is generated synchronously (which benefits small cursor sets), and is most efficient from a server resource standpoint. If you set cursor threshold to 0, all cursor keysets are generated asynchronously. With other values, the query optimizer compares the number of expected rows in the cursor set and builds the keyset asynchronously if it exceeds the number set in cursor threshold - Do not set cursor threshold too low because small result sets are better built synchronously.

37 커서 강화된 기능 SQL 서버 2000에서 커서 컴파일 플랜 커서 수행 계획
Static과 keysets에 대한 Fetch next Keyset fetch Cursor foot print (memory) I want to talk about some performance improvement that we made internally in SQL 2000. The Cursor compile plan contains the statement objects, the optimized plan (as seen in the procedure cache), and compile time representation of the variables that would be used, and compiled metadata. For individual uses of the cursor, there would be an individual runtime component that contains variable pointers, meta-data, expressions that are required ( but not stated in the query) This is used to create the cursor. In Shiloh we have optimized the allocation of this object – by reinitialization and reusing on the next invocation of the same cursor. The Cursor execution plan is the a representation that contains actual variable and run time information. It calls the execution plan (representation of the query tree). There is an execution context piece that contains the cursor context. It is saved and now can be reattached / initialized / used …. Fetch next has been optimized for the static and keyset cursors. These 2 have a worktable that is generated (containing a clustered index – simple b-tree). In SQL7 on fetchnext, we would ask for locks on a range of values. This has been changed in SQL2000 to ask for an unbounded range – Allowing future fetchnexts to move onto sibling rows and not retraverse the index on the worktable. Keyset fetch – again there is generally a worktable for the cursor which contains the index values for the cusor – As we process the keyset query and pass results onto the TDS stream, we might have to validate whether data has been changing We have optimized checking of the timestamp and rids of the non-clustered columns. In terms of scaling, we continue the work started in SQL7 on optimizing the cursor footprint – for SQL2000, you can see 5-15% improvement in the memory requirements for the cursor footprint, with simple keyset cursor seeing the best benefit. The SQL team is continually working on performance improvements to assist performance and scaling. To repeat, these are all internal Cursor enhancement in SQL2000 – the are automatic and do not require change to an application. Cursor compile plan – with batch – save allocation of object – reused on the next invocation of same cursor Cursor execution plan – representation of cursor is cached …. (??? Temp table is null (no resources) ) Fetch next – for static and keyset cursors are optimized Keyset fetch is very much optimized Cursor foot print is optimized G2: Plan – reused on next invocation of same cursor Execution – representation of cursor is cached …. Alazel:

38 개별 행 접근 시 향상된 기능 SQL Server 2000
Selects 내부 메모리에 정보 사용 컬럼 접근 속도 향상 IRow interface (OLE-DB) 단일 행 접근 시 직접 접근 연속적인 다음행 접근 When we worked with partners, it is apparent that much of the select work load (50 – 80% is some cases) can be singleton fetches ( or a small number of rows from a single table). There has been a lot of work on the singleton fetches – for this We focused on improving this performance internally within SQL Server 2000 – looking at this from a client side perspective Select performance has been enhanced – eliminating 1 or 2 memcopies – in these optimized case, the data is copied from a network buffer directly to the user space buffer – without any staging copies We also optimized column access by speeding up processing from the n/w buffer Both these changes are automatic in SQL Server 2000 without any changes required in the application code. Our interface folks looked at the same issue, and have worked on the Irow interface in OLE/DB. IRow interface implementation in SQLOLEDB is simplified to increase performance. IRow allows direct access to columns of a single row object. If you know ahead of time that the result of a command execution will produce exactly one row, IRow will retrieve the columns of that row. If the result set includes multiple rows, IRow will expose only the first row. IRow implementation does not allow any navigation of the row. Each column in the row is accessed only once with one exception: a column can be accessed twice, once to find the column size, and again to fetch the data. An additional change is the savings of a round-trip using IRow: - In server terminology - with Irowset, you would have the execute issued by the client, the sever sends down a handle, on which a fetch would occur - Now, with Irow, you would have the execute issued, and the rowset would be returned on the backleg of the round-trip sada – singleton not related to cursors only …. Singleton fetches --- n/w to user buffer directly – save at least 1 memcoy

39 예제 Dynamic Cross-Tab 만들기
Create Proc up_Cross_tab AS …. Create Table #CrossTab (ColKey varchar(20)) While … exec ('ALTER TABLE #Matrix ADD…' ) DECLARE Data_Cursor CURSOR FOR WHILE = 0 BEGIN ….. END SELECT * FROM #CrossTab When we worked with partners, it is apparent that much of the select work load (50 – 80% is some cases) can be singleton fetches ( or a small number of rows from a single table). There has been a lot of work on the singleton fetches – for this We focused on improving this performance internally within SQL Server 2000 – looking at this from a client side perspective Select performance has been enhanced – eliminating 1 or 2 memcopies – in these optimized case, the data is copied from a network buffer directly to the user space buffer – without any staging copies We also optimized column access by speeding up processing from the n/w buffer Both these changes are automatic in SQL Server 2000 without any changes required in the application code. Our interface folks looked at the same issue, and have worked on the Irow interface in OLE/DB. IRow interface implementation in SQLOLEDB is simplified to increase performance. IRow allows direct access to columns of a single row object. If you know ahead of time that the result of a command execution will produce exactly one row, IRow will retrieve the columns of that row. If the result set includes multiple rows, IRow will expose only the first row. IRow implementation does not allow any navigation of the row. Each column in the row is accessed only once with one exception: a column can be accessed twice, once to find the column size, and again to fetch the data. An additional change is the savings of a round-trip using IRow: - In server terminology - with Irowset, you would have the execute issued by the client, the sever sends down a handle, on which a fetch would occur - Now, with Irow, you would have the execute issued, and the rowset would be returned on the backleg of the round-trip sada – singleton not related to cursors only …. Singleton fetches --- n/w to user buffer directly – save at least 1 memcoy

40 Demo Ad-Hoc Plan Caching Auto-Parameterization Stored Procedures
Reduced Round-Trips Cursor When we worked with partners, it is apparent that much of the select work load (50 – 80% is some cases) can be singleton fetches ( or a small number of rows from a single table). There has been a lot of work on the singleton fetches – for this We focused on improving this performance internally within SQL Server 2000 – looking at this from a client side perspective Select performance has been enhanced – eliminating 1 or 2 memcopies – in these optimized case, the data is copied from a network buffer directly to the user space buffer – without any staging copies We also optimized column access by speeding up processing from the n/w buffer Both these changes are automatic in SQL Server 2000 without any changes required in the application code. Our interface folks looked at the same issue, and have worked on the Irow interface in OLE/DB. IRow interface implementation in SQLOLEDB is simplified to increase performance. IRow allows direct access to columns of a single row object. If you know ahead of time that the result of a command execution will produce exactly one row, IRow will retrieve the columns of that row. If the result set includes multiple rows, IRow will expose only the first row. IRow implementation does not allow any navigation of the row. Each column in the row is accessed only once with one exception: a column can be accessed twice, once to find the column size, and again to fetch the data. An additional change is the savings of a round-trip using IRow: - In server terminology - with Irowset, you would have the execute issued by the client, the sever sends down a handle, on which a fetch would occur - Now, with Irow, you would have the execute issued, and the rowset would be returned on the backleg of the round-trip sada – singleton not related to cursors only …. Singleton fetches --- n/w to user buffer directly – save at least 1 memcoy

41 General Performance 추가 권고 사항
배치 프로세싱 처리 하라. (inserts와 selects를 한 배치에) Combine inserts Network Library의 자원 공유 SAN(System Area Network) 사용 고려 I would like about some other general performance issues that we have worked on and found recently when working with our ISV partners: Default: Inserts can account for a good portion of an application suite, and the inserts can have many columns set to the default value. In SQLServer the processing of DEFAULT parameter is made more efficient by short-circuiting many type checks & data initialization. In addition, when processing stored procedures with default parameters, the default values are retrieved and copied only when the parameter value changes from default to non default. Batch Processing: Consider the case of Tables where batch Inserts are done as part of the application suite. This is purely an application optimization. You could consider putting multiple inserts into the same SP (for example up to 5)– For each combined insert in the SP, you could save the overhead of instructions for setup, compile plan look up etc. Shared memory: You can have situations where you run batch jobs on the database server, Or run a virtual 3-tier (with the app server and SQL Server running on the same machine, The shared memory netlib in SQLServer will improve performance – RPC do not go across the n/w stack like TCP/IP and have to be processed, but can utilize the shared memory netlib. SAN - We work very well with the new System Area Network technology (servernet or giganet) These are high bandwidth, low latency and reliable methods. By using native interface we eliminate the TCP stack overhead and the kernal time associated with it. On one ISV industry benchmark, we reduced kernal time by 1/3 The SD benchmark for 4500 users does around network Ios (nearly equal amounts of reads\writes). The avg read is around 700 bytes while the write is around 1300 bytes. This amounts to around 21 MB/Sec lan traffic. The kernal time for doing this using Gigabit Ethernet card is around 30%. The database working set for the benchmark resides in the memory and so lo+ gging is the main component of the disk ios done during the benchmark run. For 4500 SD users this typically runs to 200 disk Ios [3 MB/sec]. By switching to SAN and using native VI interface the Kernal time is cut to less than 10%. The overall gain that was achieved using SAN\native VI is little over 20%.

42 Connection Pooling SQL Server에 대한 클라이언트 커넥션의 재사용
네트웍 트래픽과 CPU의 부하를 줄일수 있다. SQL 서버의 메모리 자원을 적게 사용한다. Connection pooling enables an application to use a connection from a pool of connections that do not need to be reestablished for each use. Once a connection has been created and placed in a pool, an app can reuse that connection without the cost hit for complete connection process. Using a pooled connection can result in significant performance gains, because applications can save the overhead involved in making a connection – You can see how this could be very significant for application middle-tier that connect over the network, But also consider a client app that could benefit from multiple connections to the database. When an order entry screen has been filled in and the ok has been processed, threads could be kicked off to check inventory, credit etc. while the main thread starts totaling. This could benefit from connection pooling so that the app does not have to synchronize access by the various threads to its one 1 connection When connection pooling is enabled, a request for a connection comes to the driver manager and is handled in one of three ways: If there are no connections in the pool, a new connection is created and passed to the user. If connections are available in the pool and the connection properties (User ID, Password, and so on) requested by the client match the connection properties of the pooled connection, the client is given the open connection in the pool. If connections are available but the connection properties do not match, a new connection with the appropriate properties will be created for the client. You will see perf gains from reduced n/w traffic and latency and server CPU - I.e. 870K clocks/connection on the server - reusing a pooled connection has not network latency Options will determine the pool behavior - per driver or per environment - strict or relaxed matching OLE/DB - When using the drivermanger to connect to SQL Server, you get the service components – so to use OLE DB resource pooling, the consumer must obtain its data source object by calling IDataInitialize or IDBPromptInitialize to ensure that OLE DB services are enabled. So, if you use IDataInitialize...which there's little reason you wouldn't when connecting to SQL ....you will ALWAYS have pooling. ODBC _ Enable connection pooling by calling SQLSetEnvAttr and set the Connection pooling environment attrivute to OnePerDriver The actual connection to be used is not determined by the DriverManager until SQLConnect or SQLDriverConnect is called to make the conneciton Call SQLDisconnect – returns to the connection pool When connection pooling is enabled, a request for a connection comes to the driver manager and is handled in one of three ways: If connections are available in the pool and the connection properties (User ID, Password, and so on) requested by the client match the connection properties of the pooled connection, the client is given the open connection in the pool. If connections are available but the connection properties do not match, a new connection with the appropriate properties will be created for the client.

43 Summary 강력한 수행 계획의 케싱을 위한 커서 SQL 서버 2000 내부적으로 최적화를 지원하는 다양한 잊점을 사용하자!
저장 프로시저 Prepare/Execute 파라메터화(Parameterize) 커서 효과 적인 커서 타입 설정 Test for downgrade SQL 서버 2000 내부적으로 최적화를 지원하는 다양한 잊점을 사용하자! To summarize: Work on making effective use of the SQL Server plan cache. Use stored procedures – especially for business logic that can be scaling bottlenecks Parameterize and use prepare/execute instead of ExecDirect Please consider the most cost effective cursor strategy – First default result set or firehose And then FFO-AF Consider the richer cursor models for the functionality if needed. Please test for cursor downgrade in your development builds – and see if you have a better option We have worked closely with ISVs, and built many performance and scalable improvements into SQL Server 2000, so that they can be used automatically with SQL2000.

44 SQL Server Today… CRM ERP E-Commerce Data Warehousing
We have worked with many ISV on performance and scalability issues for SQL Server 2000 in many application areas. This drove many of the optimizations into SQL200 – many of these are automatic with 2000, but some require changes by the application. These have resulted in significant performance improvements with early proof being in the performance numbers that were release with the Window2000 announcement a couple of weeks ago. We announced for instance the best SAP numbers on NT 6700 SDE concurrent users, beating the db competition by 30+%, and the best overall number any platform, any database for PeopleSoft Financials and HRMS users. Prepare/Execute – take advantage of the reduction of round trips and get the advantage of the handle for execution Meta data to client-side once, Reduced processing of the meta data Index creation during backup Impressive gains using SAN technology Optimized for default row set and the FFO-AF Parametrization Good use of sp – especially for business logic that effect concurrency

45 More Information… Books On-Line Beta2 News groups SQL Server Home page
Microsoft.beta.Shiloh.* SQL Server Home page Microsoft Product Support Services

46 Questions And Feedback

47


Download ppt "SQL Server™ 2000에서 성능 좋은 어플리케이션 구현하기"

Similar presentations


Ads by Google