블로그 이미지
SQL Server VS. 석이 minsouk@hotmail.com MSSQL 쿼리성능 관련해 궁금한 사항이 있다면 언제나 누구나 TeamViewer + Line (네이버 japan 메신저) 에 minsouk1 추가 후 연락주세요~ 010-9967-0955 보미아빠

카테고리

보미아빠, 석이 (441)
밥벌이 (16)
싸이클 (1)
일상 (1)
Total196,519
Today22
Yesterday61

달력

« » 2017.12
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

공지사항

SQL Server I/O Basic

밥벌이 / 2010.10.11 13:09


http://technet.microsoft.com/en-us/library/cc966500.aspx
http://technet.microsoft.com/en-us/library/cc917726.aspx
http://blogs.technet.com/b/josebda/archive/2009/03/31/sql-server-2008-i-o-performance.aspx

 

Microsoft SQL Server IO Internals.pptx



읽기의 물리적인 단위는 extents 이고 논리적인 읽기의 단위는 page 이다. 쓰기의 물리적인 단위는 page 이다.
그리고, 823,824 등등 오류의 정의도 볼 수 있다.

Object ID

This is the ID of the object to which the page is assigned within the schema of the database. A page can be assigned to only a single object. When the page is read from disk, the object ID is checked on the page. If the object ID does not match the expected object ID, SQL Server will generate Error 605.

SQL Server often performs its writes on page-sized, 8-KB, or larger boundaries.

Extents

SQL Server generally (except for nonmixed extents) allocates space an extent at a time. An extent is eight 8-KB pages, or 64 KB. SQL Server often performs reads in extent-sized (64 KB or 128 KB) boundaries as well.

신고
Posted by 보미아빠

SQL SERVER TRACEFLAG

분류없음 / 2010.10.08 15:37
http://www.sqlservercentral.com/articles/trace+flags/70131/


flag Trace Flag Description (underlined are sp_configure’able)
-1 Sets trace flags for all connections. Used only with DBCC TRACEON and TRACEOFF. The setting of the Trace flag -1 is not visible with DBCC TRACESTATUS command, but work without problems.
105 SQL Server 6.5 you can use maximum 16 tables or subqueries in a single select statement. There is no documented way, to avoid this restriction, but you can use undocumented trace flag 105 for this purpose.
106 Disables line number information for syntax errors.
107 Interprets numbers with a decimal point as float instead of decimal.
110 Turns off ANSI select characteristics.
204 A backward compatibility switch that enables non-ansi standard behavior. E.g. previously SQL server ignored trailing blanks in the like statement and allowed queries that contained aggregated functions to have items in the group by clause that were not in the select list.
205 Report when a statistics-dependent stored procedure is being recompiled as a result of AutoStat.
206 Provides backward compatibility for the setuser statement.
208 SET QUOTED IDENTIFIER ON.
237 Tells SQL Server to use correlated sub-queries in Non-ANSI standard backward compatibility mode.
242 Provides backward compatibility for correlated subqueries where non-ANSI-standard results are desired.
243 The behavior of SQL Server is now more consistent because null ability checks are made at run time and a null ability violation results in the command terminating and the batch or transaction process continuing.
244 Disables checking for allowed interim constraint violations. By default, SQL Server checks for and allows interim constraint violations. An interim constraint violation is caused by a change that removes the violation such that the constraint is met, all within a single statement and transaction. SQL Server checks for interim constraint violations for self-referencing DELETE statements, INSERT, and multi-row UPDATE statements. This checking requires more work tables. With this trace flag you can disallow interim constraint violations, thus requiring fewer work tables.
246 Derived or NULL columns must be explicitly named in a select….INTO or create view statement when not done they raise an error. This flag avoids that.
253 Prevents ad-hoc query plans to stay in cache.
257 Will invoke a print algorithm on the XML output before returning it to make the XML result more readable.
260 Prints versioning information about extended stored procedure dynamic-link libraries (DLLs). For more information about __GetXpVersion(), see Creating Extended Stored Procedures. Scope: global or session
262 SQL 7 - Trailing spaces are no longer truncated from literal strings in CASE statements. Used after hotfix 891116
302 Should be used with flag 310 to show the actual join ordering. Prints information about whether the statistics page is used, the actual selectivity (if available), and what SQL Server estimated the physical and logical I/O would be for the indexes.
310 Prints information about join order. Index selection information is also available in a more readable format using SET SHOWPLAN_ALL, as described in the SET statement.
320 Disables join-order heuristics used in ANSI joins. To see join-order heuristics use flag 310. SQL Server uses join-order heuristics to reduce the no’ of permutations when using the best join order.
323 Reports on the use of update statements using UPDATE in place. Shows a detailed description of the various update methods used by SQL Server 6.5.
325 Prints information about the cost of using a non-clustered index or a sort to process an ORDER BY clause.
326 Prints information about the estimated & actual costs of sorts. Instructs the server to use arithmetic averaging when calculating density instead of a geometric weighted average when updating statistics.  Useful for building better stats when an index has skew on the leading column.  Use only for updating the stats of a table/index with known skewed data.
330 Enables full output when using the SET SHOWPLAN_ALL option, which gives detailed information about joins.
342 Disables the costing of pseudo-merge joins, thus significantly reducing time spent on the parse for certain types of large, multi-table joins. One can also use SET FORCEPLAN ON to disable the costing of pseudo-merge joins because the query is forced to use the order specified in the FROM clause.
345 Increase the accuracy of choice of optimum order when you join 6 or more tables.
506 Enforces SQL-92 standards regarding null values for comparisons between variables and parameters. Any comparison of variables and parameters that contain a NULL always results in a NULL.
610

SQL 10 – Enable the potential for minimal-logging when:

·   Bulk loading into an empty clustered index, with no nonclustered indexes

·   Bulk loading into a non-empty heap, with no nonclustered indexes

611 After SQL 9 when turned on, each lock escalation is recorded in the SQL Server error log along with the SQL Server handle number.
652 Disables read ahead for the server.
653 Disables read ahead for the current connection.
661 Disables the ghost record removal process. A ghost record is the result of a delete operation. When you delete a record, the deleted record is kept as a ghost record. Later, the deleted record is purged by the ghost record removal process. When you disable this process, the deleted record is not purged. Therefore, the space that the deleted record consumes is not freed. This behavior affects space consumption and the performance of scan operations. SCOPE: Global. If you turn off this trace flag, the ghost record removal process works correctly.
806 Cause 'DBCC-style' page auditing to be performed whenever a database page is read into the buffer pool. This is useful to catch cases where pages are being corrupted in memory and then written out to disk with a new page checksum. When they're read back in the checksum will look correct, but the page is corrupt (because of the previous memory corruption). This page auditing goes someway to catching this - especially on non-Enterprise Edition systems that don't have the 'checksum sniffer'.
809 SQL 8 – Limits the amount of Lazy Write activity.
815 Enables latch enforcement. SQL Server 8 (with service pack 4) and SQL Server 9 can perform latch enforcement for data pages found in the buffer pool cache. Latch enforcement changes the virtual memory protection state while database page status changes from "clean" to "dirty" ("dirty" means modified through INSERT, UPDATE or DELETE operation). If an attempt is made to modify a data page while latch enforcement is set, it causes an exception and creates a mini-dump in SQL Server installation's LOG directory. Microsoft support can examine the contents of such mini-dump to determine the cause of the exception. In order to modify the data page the connection must first acquire a modification latch. Once the data modification latch is acquired the page protection is changed to read-write. Once the modification latch is released the page protection changes back to read-only.
818 SQL 8 enables in memory ring buffer used to track last 2048 successful write operations.
830 SQL 9 – disable the reporting of CPU Drift errors in the SQL Server errorlog like SQL Server has encountered 2 occurrence(s) of I/O requests taking longer than 15 seconds to complete
834 Causes SQL Server to use Windows large-page allocations for the memory that is allocated for the buffer pool. The page size varies depending on the hardware platform, but the page size may be from 2 MB to 16 MB. Large pages are allocated at startup and are kept throughout the lifetime of the process. Trace flag 834 improves performance by increasing the efficiency of the translation look-aside buffer (TLB) in the CPU.
Flag 834 applies only to 64-bit versions of SQL Server. You must have the Lock pages in memory user right to turn on trace flag 834. You can turn on trace flag 834 only at startup.
Trace flag 834 may prevent the server from starting if memory is fragmented and if large pages cannot be allocated. Therefore, trace flag 834 is best suited for servers that are dedicated to SQL Server.
For more information about large-page support, http://msdn2.microsoft.com/en-us/library/aa366720.aspx(http://msdn2.microsoft.com/en-us/library/aa366720.aspx)
835 SQL 9 & 10. For 64 bit SQL Server. This turns off Lock pages in memory.
836 Causes SQL Server to size the buffer pool at startup based on the value of the max server memory option instead of based on the total physical memory. You can use trace flag 836 to reduce the number of buffer descriptors that are allocated at startup in 32-bit Address Windowing Extensions (AWE) mode.
Trace flag 836 applies only to 32-bit versions of SQL Server that have the AWE allocation enabled. You can turn on trace flag 836 only at startup.
845 SQL 9 & 10. For 64 bit SQL Server. This turns on Lock pages in memory.
1117 Grows all data files at once, else it goes in turns.
1118 Switches allocations in tempDB from 1pg at a time (for first 8 pages) to one extent. There is now a cache of temp tables. When a new temp table is created on a cold system it uses the same mechanism as for SQL 8. When it is dropped though, instead of all the pages being deallocated completely, one IAM page & one data page are left allocated, then the temp table is put into a special cache. Subsequent temp table creations will look in the cache to see if they can just grab a pre-created temp table. If so, this avoids accessing the allocation bitmaps completely. The temp table cache isn't huge (32 tables), but this can still lead to a big drop in latch contention in tempdb. http://www.sqlskills.com/BLOGS/PAUL/post/Misconceptions-around-TF-1118.aspx
1180 Forces allocation to use free pages for text or image data and maintain efficiency of storage. 1197 applies only in the case of SQL 7 – SP3. Helpful in case when DBCC SHRINKFILE and SHRINKDATABASE commands may not work because of sparsely populated text, ntext, or image columns
1197
1200 Prints lock information (the process ID and type of lock requested).
1202 Insert blocked lock requests into syslocks.
1204 Returns resources and types of locks participating in a deadlock and command affected. Scope: global only
1205 More detailed information about the command being executed at the time of a deadlock. This trace flag was documented in SQL Server 7.0 Books Online, but was not documented in SQL Server 8.
1206 Used to complement flag 1204 by displaying other locks held by deadlock parties
1211

Disables lock escalation based on memory pressure, or based on number of locks. The SQL Server Database Engine will not escalate row or page locks to table locks.

Using this trace flag can generate excessive numbers of locks. This can slow the performance of the Database Engine, or cause 1204 errors (unable to allocate lock resource) because of insufficient memory. For more information, see Lock Escalation (Database Engine).

If both trace flag 1211 and 1224 are set, 1211 takes precedence over 1224. However, because trace flag 1211 prevents escalation in every case, even under memory pressure, we recommend that you use 1224. This helps avoid "out-of-locks" errors when many locks are being used. Scope: global or session

1216

SQL 7 - Disables Health reporting. Lock monitor when detects a (worker thread) resource level blocking scenario. If a SPID that owns a lock is currently queued to the scheduler, because all the assigned worker threads have been created and all the assigned worker threads are in an un-resolvable wait state, the following error message is written to the SQL Server error log:

Error 1223: Process ID %d:%d cannot acquire lock "%s" on resource %s because a potential deadlock exists on Scheduler %d for the resource. Process ID %d:% d holds a lock "%h" on this resource.

1222 Returns the resources and types of locks that are participating in a deadlock and also the current command affected, in an XML format that does not comply with any XSD schema. Scope: global only
1224

Disables lock escalation based on the number of locks. However, memory pressure can still activate lock escalation. The Database Engine escalates row or page locks to table (or partition) locks if the amount of memory used by lock objects exceeds one of the following conditions:

·   40% of the memory that is used by Db Engine, exclusive of memory allocation using Address Windowing Extension (AWE). This is applicable when the locks parameter of sp_configure is set to 0.

·   Forty percent of the lock memory that is configured by using the locks parameter of sp_configure.

If both trace flag 1211 and 1224 are set, 1211 takes precedence over 1224. However, because trace flag 1211 prevents escalation in every case, even under memory pressure, we recommend that you use 1224. This helps avoid "out-of-locks" errors when many locks are being used.

Note:Lock escalation to the table- or HoBT-level granularity can also be controlled by using the LOCK_ESCALATION option of the ALTER TABLE statement.  Scope:global or session

1261

SQL 8 - Disables Health reporting. Lock monitor when detects a (worker thread) resource level blocking scenario. If a SPID that owns a lock is currently queued to the scheduler, because all the assigned worker threads have been created and all the assigned worker threads are in an un-resolvable wait state, the following error message is written to the SQL Server error log:

Error 1229: Process ID %d:%d owns resources that are blocking processes on scheduler %d.

1400 Enables the creation of the database mirroring endpoint, which is required for setting up and using database mirroring. This trace flag is allowed only when using the –T.
1462 Turns off log stream compression and effectively reverts the behavior back to ver 9.
1603 Use standard disk I/O (i.e. turn off asynchronous I/O).
1609 Turns on the unpacking and checking of remote procedure call (RPC) information in Open Data Services. Used only when applications depend on the old behavior.
1610 Boot the SQL dataserver with TCP_NODELAY enabled.
1611 If possible, pin shared memory -- check errorlog for success/failure.
1704 Prints information when a temporary table is created or dropped.
1717 Causes new objects being created to be system objects.
1806 Disables instant file initialization.
1807 Allows creating a database file on a mapped or UNC network location. unsupported under SQL Server 7 & 8.
2301 Enables advanced optimizations that are specific to decision support queries. This option applies to decision support processing of large data sets.
2330 Stops the collection of statistics for sys.db_index_usage_stats.
2382 Statistics collected for system tables.
2389 SQL 9 – Tracks the nature of columns by subsequent statistics updates. When SQL Server determines that the statistics increase three times, the column is branded ascending. The statistics will be updated automatically at query compile.
2390 Does the same like 2389 even if ascending nature of the column is not known and -- never enable without 2389.
2440 Parallel query execution strategy on partitioned tables. SQL 9 – uses a single thread per partition parallel query execution strategy. In ver. 10, multiple threads can be allocated to a single partition, thus improving the query’s response time.
2505 Prevents DBCC TRACEON 208, SPID 10 errors from appearing in the error log.
2508 Disables parallel non-clustered index checking for DBCC CHECKTABLE.
2509 Used with DBCC CHECKTABLE.html to see the total count of ghost records in a table
2520 Force DBCC HELP to return syntax of undocumented DBCC statements. If 2520 is not turned on, DBCC HELP will refuse to give you the syntax stating: "No help available for DBCC statement 'undocumented statement'".
2528

Disables parallel checking of objects by DBCC CHECKDB, CHECKFILEGROUP and CHECKTABLE. By default, the degree of parallelism is automatically determined by the query processor. The maximum degree of parallelism is configured just like that of parallel queries. For more information, see max degree of parallelism Option.

Parallel DBCC should typically be left enabled. For DBCC CHECKDB, the query processor reevaluates and automatically adjusts parallelism with each table or batch of tables checked. Sometimes, checking may start when the server is almost idle. An administrator who knows that the load will increase before checking is complete may want to manually decrease or disable parallelism.

Disabling parallel checking of DBCC can cause it to take much longer to complete and if DBCC is run with the TABLOCK feature enabled and parallelism set off, tables may be locked for longer periods of time.

Scope: global or session

2537 SQL 9 & 10. Allows function ::fn_dblog to look inside all logs (not just the active log).
2542 SQL 8 – Used with Sqldumper.exe to get certain dumps. In range 254x – 255x.
2551 Adds additional information to the dump file.
2701 Sets the @@ERROR system function to 50000 for RAISERROR messages with severity levels of 10 or less. When disabled, sets the @@ERROR system function to 0 for RAISERROR messages with severity levels of 10 or less.
2861 Cache query plans for queries that have a cost of zero or near to zero.
3001 Stops sending backup entries into MSDB.
3004 Gives out more detailed information about restore & backup activities.
3031 SQL 9 - will turn the NO_LOG and TRUNCATE_ONLY options into checkpoints in all recovery modes.
3104 Causes SQL Server to bypass checking for free space.
3111 Cause LogMgr::ValidateBackedupBlock to be skipped during backup and restore operations.
3205 If a tape drive supports hardware compression, either the DUMP or BACKUP statement uses it. With this trace flag, you can disable hardware compression for tape drivers. This is useful when you want to exchange tapes with other sites or tape drives that do not support compression. Scope: global or session
3213 Trace SQL Server activity during backup process so that we will come to know which part of backup process is taking more time.
3222 Disables the read ahead that is used by the recovery operation during roll forward operations.
3226 With this trace flag, you can suppress BACKUP COMPLETED log entries going to WIN and SQL logs.
3231 SQL 8 & 9 - will turn the NO_LOG and TRUNCATE_ONLY options into no-ops in FULL/BULK_LOGGED recovery mode, and will clear the log in SIMPLE recovery mode.
3282 SQL 6.5 – Used after backup restoration fails refer to microsoft for article Q215458.
3422 Cause auditing of transaction log records as they're read (during transaction rollback or log recovery). This is useful because there is no equivalent to page checksums for transaction log records and so no way to detect whether log records are being corrupted e careful with these trace flags - I don't recommend using them unless you are experiencing corruptions that you can't diagnose. Turning them on will cause a big CPU hit because of the extra auditing that's happening.
3502 Tracks CHECKPOINT - Prints a message to the log at the start and end of each checkpoint.
3503 Indicates whether the checkpoint at the end of automatic recovery was skipped for a database (this applies only to read-only databases).
3504 For internal testing. Will raise a bogus log-out-of-space condition from checkpoint()
3505 Disables automatic checkpoints. May increase recovery time and can prevent log space reuse until the next checkpoint is issued. Make sure to issue manual checkpoints on all read/write databases at appropriate time intervals.
Note does not prevent the internal checkpoints that are issued by certain commands, such as BACKUP.
3601 Stack trace when error raised. Also see 3603
3602 Records all error and warning messages sent to the client.
3603 SQL Server fails to install on tricore, Bypass SMT check is enabled, flags are added via registry. Also see 3601.
3604 Sends trace output to the client. This trace flag is used only when setting trace flags with DBCC TRACEON and DBCC TRACEOFF.
3605 Sends trace output to the error log.  (if SQL Server is started from CMD output also appears on the screen)
3607 Trace flag 3607 skips the recovery of databases on the startup of SQL Server and clears the TempDB. Setting this flag lets you get past certain crashes, but there is a chance that some data will be lost
3608 Prevents SQL Server from automatically starting and recovering any database except the master database. Databases will be started and recovered when accessed. Some features, such as snapshot isolation and read committed snapshot, might not work.
3609 Skips the creation of the tempdb database at startup. Use this trace flag if the device or devices on which tempdb resides are problematic or problems exist in the model database.
3610 SQL 9. Divide by zero to result in NULL instead of error.
3625 Limits the amount of information returned in error messages. For more information, see Metadata Visibility Configuration. Scope: global only
3626 Turns on tracking of the CPU data for the sysprocesses table.
3640 Eliminates the sending of DONE_IN_PROC messages to the client for each statement in a stored procedure. This is similar to the session setting of SET NOCOUNT ON, but when set as a trace flag, every client session is handled this way.
3689 Logs extended errors to errorlog when network disconnect occurs, turned off by default. Will dump out the socket error code this can sometimes give you a clue as to the root cause.
3913 SQL 7/8 – SQL Server does not update the rowcnt column of the sysindexes system table until the transaction is committed. When turned on the optimizer gets row count information from in-memory metadata that is saved to sysindexes system table when the transaction commits.
4013

This trace flag writes an entry to the SQL Server error log when a new connection is established. For each connection that occurs, the trace flag writes two entries that look like this:

Login: sa saSQL Query Analyzer(local)ODBCmaster, server process ID (SPID): 57, kernel process ID (KPID): 57.
Login: sa XANADUsaSQL Query Analyzer(local)ODBCmaster, server process ID (SPID): 57, kernel process ID (KPID): 57.

4022 If turns on, then automatically started procedures will be bypassed.
4029 Logs extended errors to errorlog when network disconnect occurs, turned off by default. Will dump out the socket error code this can sometimes give you a clue as to the root cause.
4030 Prints both a byte and ASCII representation of the receive buffer. Used when you want to see what queries a client is sending to SQL Server. You can use this trace flag if you experience a protection violation and want to determine which statement caused it. Typically, you can set this flag globally or use SQL Server Enterprise Manager. You can also use DBCC INPUTBUFFER.
4031 Prints both a byte and ASCII representation of the send buffers (what SQL Server sends back to the client). You can also use DBCC OUTPUTBUFFER.
4032 Traces the SQL commands coming in from the client. The output destination of the trace flag is controlled with the 3605/3604 trace flags.
4101

SQL 9 - Query that involves an outer join operation runs very slowly. However, if you use the FORCE ORDER query hint in the query, the query runs much faster. Additionally, the execution plan of the query contains the following text in theWarnings column:  NO JOIN PREDICATE

Turn these trace flags after HOTFIX is applied (SP2 CUP4)

4121
4606 Over comes SA password by startup. Refer to Ms article 936892.
4612 Disable the ring buffer logging - no new entries will be made into the ring buffer.
4613 Generate a minidump file whenever an entry is logged into the ring buffer.
4616 Makes server-level metadata visible to application roles. In SQL Server, an application role cannot access metadata outside its own database because application roles are not associated with a server-level principal. This is a change of behavior from earlier versions of SQL Server. Setting this global flag disables the new restrictions, and allows for application roles to access server-level metadata. Scope: global only
5302 Alters default behavior of select…INTO (and other processes) that lock system tables for the duration of the transaction. This trace flag disables such locking during an implicit transaction. 
6527

Disables generation of a memory dump on the first occurrence of an out-of-memory exception in CLR integration. By default, SQL Server generates a small memory dump on the first occurrence of an out-of-memory exception in the CLR. The behavior of the trace flag is as follows:

·   If this is used as a startup trace flag, a memory dump is never generated. However, a memory dump may be generated if other trace flags are used.

·   If this trace flag is enabled on a running server, a memory dump will not be automatically generated from that point on. However, if a memory dump has already been generated due to an out-of-memory exception in the CLR, this trace flag will have no effect. Scope: global only

7103 Disable table lock promotion for text columns. Refer to Ms article - 230044
7300 Retrieves extended information about any error you encounter when you execute a distributed query.
7501 Dynamic cursors are used by default on forward-only cursors. Dynamic cursors are faster than in earlier versions and no longer require unique indexes. This flag disables the dynamic cursor enhancements and reverts to version 6.0 behavior.
7502 Disables the caching of cursor plans for extended stored procedures.
7505 Enables version 6.x handling of return codes when calling dbcursorfetchex and the resulting cursor position follows the end of the cursor result set.
7525 Reverts to the SQL Server 7 behavior of closing nonstatic cursors regardless of the SET CURSOR_CLOSE_ON_COMMIT state in SQL Server 8.
7601 Turns on full text indexing. Together these four gather more information about full text search (indexing process) to the error log.
7603
7604
7605
7646 SQL 10. Avoids blocking when using full text indexing. An issue we experienced that full text can be slow when there is a high number of updates to the index and is caused by blocking on the docidfilter internal table.
7806 Enables a dedicated administrator connection (DAC) on SQL Svr Express. By default, no DAC resources are reserved on SQL Server Express.
8004 SQL server to create a mini dump once you enable 2551 and a out of memory condition is hit.
8011 Disables the collection of additional diagnostic information for Resource Monitor. You can use the information in this ring buffer to diagnose out-of-memory conditions. Scope: GLOBAL.
8012

Records an event in the schedule ring buffer every time that one of the following events occurs:

·   A scheduler switches context to another worker.

·   A worker is suspended or resumed.

·   A worker enters the preemptive mode or the non-preemptive mode.

You can use the diagnostic information in this ring buffer to analyze scheduling problems. For example, you can use the information in this ring buffer to troubleshoot problems when SQL Server stops responding.
Trace flag 8012 disables recording of events for schedulers. You can turn on trace flag 8012 only at startup.

8018 Disables the creation of the ring buffer, and no exception information is recorded. The exception ring buffer records the last 256 exceptions that are raised on a node. Each record contains some information about the error and contains a stack trace. A record is added to the ring buffer when an exception is raised.
8019 Disables stack collection during the record creation, has no effect if trace flag 8018 is turned on. Disabling the exception ring buffer makes it more difficult to diagnose problems that are related to internal server errors. You can turn on trace flag 8018 and trace flag 8019 only at startup.
8020 SQL Server uses the size of the working set when SQL Server interprets the global memory state signals from the operating system. Trace flag 8020 removes the size of the working set from consideration when SQL Server interprets the global memory state signals. If you use this trace flag incorrectly, heavy paging occurs, and the performance is poor. Therefore, contact Microsoft Support before you use. You can turn on trace flag 8020 only at startup
8033 SQL 9 – disable the reporting of CPU Drift errors in the SQL Server errorlog like time stamp counter of CPU on scheduler id 1 is not synchronized with other CPUs.
8202 Used to replicate UPDATE as DELETE/INSERT pair at the publisher. i.e. UPDATE commands at the publisher can be run as an "on-page DELETE/INSERT" or a "full DELETE/INSERT". If the UPDATE command is run as an "on-page DELETE/INSERT," the Logreader send UDPATE command to the subscriber, If the UPDATE command is run as a "full DELETE/INSERT," the Logreader send UPDATE as DELETE/INSERT Pair. If you turn on trace flag 8202, then UPDATE commands at the publisher will be always send to the subscriber as DELETE/INSERT pair.
8206 Supports stored procedure execution with a user specified owner name for SQL Server subscribers or without owner qualification for heterogeneous subscribers in SQL Server 8.
8207 Enables singleton updates for Transactional Replication, released with SQL Server 8 SP 1.
8501 Writes detailed information about Ms-DTC context & state changes to the log.
8599 Allows you to use a savepoint within a distributed transaction.
8602 Ignore index hints that are specified in query/procedure.
8679 Prevents the SQL Server optimizer from using a Hash Match Team operator.
8687 Used to disable query parallelism.
8721 Dumps information into the error log when AutoStat has been run.
8722 Disable all other types of hints. This includes the OPTION clause.
8744 Disables pre-fetching for the Nested Loops operator. Incorrect use of this trace flag may cause additional physical reads when SQL Server executes plans that contain the Nested Loops operator. For more information about the Nested Loops operator, see the "Logical and physical operators reference" topic in SQL Server 9 BOL.
You can turn on trace flag 8744 at startup or in a user session. When you turn on trace flag 8744 at startup, the trace flag has global scope. When you turn on trace flag 8744 in a user session, the trace flag has session scope.
8755 Disable any locking hints like READONLY. By setting this, you allow SQL Server to dynamically select the best locking hint for the query.
8783 Allows DELETE, INSERT, and UPDATE statements to honor the SET ROWCOUNT ON setting when enabled.
8816 Logs every two-digit year conversion to a four-digit year.
9134 SQL 8 – Does additional reads to test if the page is allocated & linked correctly this checks IAM & PFS. Fixes error 601 for queries under Isolation level read uncommitted.
9268

SQL 8 – When SQL Server runs a parameterized query that contains several IN clauses, each with a large number of values, SQL Server may return the following error message after a minute or more of high CPU utilization:

Server: Msg 8623, Level 16, State 1
Internal Query Processor Error: The query processor could not produce a query plan. Contact your primary support provider for more information.

http://support.microsoft.com/kb/325658 Enabling this trace flag activates the hotfix.


http://msdn.microsoft.com/en-us/library/ms188396.aspx

신고
Posted by 보미아빠


미리읽기란? 

I/O 와 CPU 연산을 동시에 수행해 그 수행 성능을 최대로 만들어 보겠다 라는 최적화 알고리즘이다.
상식적으로 읽고 연산 해야 하지만, "미리 쓰일것 같아, 먼저 읽어 두겠다." 는 것이고, 그로 인해 연산을 먼저 시작할 수 있으므로 성능은 더 낳아진다. 라는 이론이다. 하지만 side effect 로 영원히 읽지 않아도 되는 것을 미리 읽어 I/O 성능을 갉아 먹을 수 있는 역 기능을 수행 할 수도 있다.

미리읽기는 IAM 을 이용하는 방법과 index 의 non-leaf 를 이용하는 방법이 있다. 이것의 작동 방식은 BOL에 상세히 나와 있다. 조금만 살펴 본다면, IAM 이 bit 단위로 extents 할당 단위를 표현하고 있고, 이 IAM 1Byte를 읽어 (8 extents = 64K * 8 = 512K) 씩 물리적 방향에 맞게 ASync 방식으로 읽을수 있다. 또 Index 의 경우,  index 의 non-leaf 를 읽어 모여있는 페이지를 몇개를 Async 로 순서에 맞게 읽을 수 있으므로, 그 성능을 좋게 할 수 있다. 핵심은 역시 I/O 와 CPU 연산을 동시에 할 수 있다는 것이 가장 크다. SQL Server EE 의 경우 미리 읽기를 더 잘 할 수 있다.

 


 

2008 R2

http://msdn.microsoft.com/en-us/library/ms191475(v=sql.105).aspx

The read-ahead mechanism allows the Database Engine to read up to 64 contiguous pages (512KB) from one file.

 

 

2000

http://technet.microsoft.com/en-us/library/cc966500.aspx

SQL Server uses the Win32 API calls as follows.

 

 

API

Common Usage

CreateFile

Used to create and open database and log files. The flags FILE_FLAG_OVERLAPPED, FILE_FLAG_WRITETHROUGH, and FILE_FLAG_NO_BUFFERING are specified to avoid nonstable media caching.

WriteFile

Primarily used by the log manager and backup manager to handle I/Os.

ReadFile

Primarily used by the log manager and backup manager to handle I/Os.

WriteFileGather

Primarily used by the buffer pool to write page groups (up to sixteen 8-KB pages in a group).

ReadFileScatter

Primarily used by the buffer pool to read pages into the buffer pool. Can be used for single page requests as well as read-ahead requests. Read-ahead requests are generally 128 pages for each group but can be as many as 1,024 pages when running Microsoft SQL Server Enterprise Edition.

HasOverlappedIoCompleted

Used to determine the status of I/O requests.

GetOverlappedResults

Used to determine success of the I/O requests.

 

 

디버깅 하니....다 나오는구만....-_- 궁금해 할 필요 없이 보면 된다....!

 


미리 읽기의 비 활성화 방법

관련 TRACE FLAG
652 Disables read ahead for the server.
653 Disables read ahead for the current connection.
3222 Disables the read ahead that is used by the recovery operation during roll forward operations.

BOL
http://msdn.microsoft.com/ko-kr/library/ms191475.aspx

좋은 아티클 테스트 포함

http://sqlblog.com/blogs/linchi_shea/archive/2008/07/04/performance-impact-some-data-points-on-read-ahead.aspx
http://technet.microsoft.com/en-us/library/cc966500.aspx
http://technet.microsoft.com/en-us/library/cc917726.aspx

위 아티클을 읽으면, 읽기의 물리적인 단위는 extents 이고 논리적인 읽기의 단위는 page 이다. 쓰기의 물리적인 단위는 page 이다. 그리고, 823,824 등등 오류의 정의도 볼 수 있다.

Object ID

This is the ID of the object to which the page is assigned within the schema of the database. A page can be assigned to only a single object. When the page is read from disk, the object ID is checked on the page. If the object ID does not match the expected object ID, SQL Server will generate Error 605.

SQL Server often performs its writes on page-sized, 8-KB, or larger boundaries.

Extents

SQL Server generally (except for nonmixed extents) allocates space an extent at a time. An extent is eight 8-KB pages, or 64 KB. SQL Server often performs reads in extent-sized (64 KB or 128 KB) boundaries as well.

Read-Ahead

SQL Server 2000 uses ReadFileScatter to perform read-ahead operations. SQL Server uses sophisticated algorithms to retrieve data pages that are going to be used in the immediate future.

For example, if you run a query that can use an index to determine applicable rows, a read-ahead may occur on the actual data pages that are needed to complete the select list. As index entries are identified, SQL Server can post OVERLAPPED (async) I/O operations for the data pages that will be used in upcoming steps of the query plan. This is how a query using a bookmark lookup operator uses read-ahead.

This example is just one of many read-ahead situations that SQL Server can use. Allowing the index searching to continue while the data page I/O is in progress maximizes the CPU and I/O of the system. The I/O is often completed by the time it is needed so other steps in the plan have direct memory access to the needed data and do not have to stall while waiting on I/O.

When a read-ahead is posted, it can be from 1 to 1,024 pages. SQL Server limits a single read-ahead request depth to 128 pages on most editions. However, Microsoft SQL Server Enterprise Edition raises the limit to 1,024 pages.

SQL Server uses the following steps to set up read-ahead.

  1. Obtain the requested amount of buffers from the free list.

  2. For each page:

    1. Determine the in-memory status of the page by doing a hash search.

    2. If found to be already in memory, set up the read-ahead request to immediately return the buffer to the free list upon I/O completion.

    3. Establish the proper I/O request information for ReadFileScatter invocation.

    4. Acquire I/O latch to protect buffer from further access.

    5. If the page is not found in hash search then insert it into the hash table.

  3. Issue the ReadFileScatter operation to read the data.

When the I/O operation is complete, each page is sanity checked for a valid page number and torn page errors. In addition, various other data integrity and safety checks are performed. The I/O latch is then released so the page is available for use if it is located on the hash chain. If the page was determined to be already in memory, the page is immediately discarded to the free list.

This process shows the key factors of SQL Server I/O patterns. Read-ahead goes after pages that can already be in memory or not allocated. Because SQL Server maintains the in-memory buffers and hash chains, SQL Server tracks the page’s state. Importantly, read-ahead processing opens the door for overlapping read and write requests at the hardware level.

If a page is already in memory when the read-ahead request is posted, the contiguous read is still needed and is faster than breaking up read requests into multiple physical requests. SQL Server considers the read to be unusable for the page in question, but many of the pages around it may be usable. However, if a write operation is in progress when the read is posted, the subsystem has to determine which image of the read to return. Some implementations return the current version of the page before the write is complete; others make the read wait until the write completes; and yet others return a combination, showing partially new data and partially old data. The key is that SQL Server will discard the read as unusable but the subsystem needs to maintain the proper image for subsequent read operations. The in-progress write, when completed, must be the next read image returned to the server running SQL Server.

Do not confuse read-ahead with parallel query plans. Read-ahead occurs independently of the parallel query plan selection. The parallel plan may drive I/O harder because multiple workers are driving the load, but read-ahead occurs for serial and parallel plans. To ensure that parallel workers do not work on the same data sets, SQL Server implements the parallel page supplier to help segment the data requests.

Reads
When a page or log block is read from disk, the checksum (page audit) value is calculated and compared to the checksum value that was stored on the page or log block. If the values do not match, the data is considered to be damaged and an error message is generated.

SQL Server uses read-ahead logic to avoid query stalls caused by I/O waits. The read-ahead design tries to keep the physical reads and checksum comparisons out of the critical path of the active query, decreasing the performance effects of checksum activity.

    Read-ahead enhanced

In SQL Server 2005, the read-ahead design is enhanced so that it reduces physical data transfer requirements by trimming the leading and trailing pages from the request if the data page(s) are already in the buffer pool.

For more information on SQL Server read-ahead logic, see SQL Server I/O Basics (http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/sqlIObasics.mspx).

For example, a read-ahead request is to be issued for pages 1 through 128 but pages 1 and 128 are already located in the SQL Server buffer pool. The read-ahead request would be for pages 2 through 127 in SQL Server 2005. In comparison, SQL Server 2000 requests pages 1 through 128 and ignores the data that is returned for pages 1 and 128.

신고
Posted by 보미아빠


SQL Server는 기동할 때 마다 모든 트랜잭션을 커밋 또는 롤백 시키기 위해서 복구(recovery) 작업을 수행한다. 이 복구 과정은 보통 수 초에서 수 분정도 소요되지만 한창 수정 작업이 진행되는 도중에 서버가 중단되었다면 복구 작업은 최소한 수정 작업이 진행된 시간 또는 로그 디바이스에 대한 경쟁 때문에 그 이상 걸릴 수 있다.

 SQL Server가 복구할 수 있는 충분한 시간을 주도록 하고 현재와 과거의 에러 로그 파일 및 NT의 에러 로그를 점검하여 어떤 문제가 발생하지는 않았는지 확인해야 한다. 만약 하드웨어 문제나 SQL Server의 버그가 발생하였다면 에러가 기록되어 있을 것이다.

 복구 작업이 CPU와 다스크를 사용하는지 알아보기 위해서 디스크의 작동상황을 알려주는 램프와 sysprocesses 활동 상황을 점검한다. 매우 드문 경우이긴 하지만 SQL Server가 데이터베이스를 정확하게 복구하지 못할 수도 있다.

 복구 과정을 확인하는 그 밖의 방법으로는 각 트랜잭션이 롤포워드(roll forward) 또는 롤백(rollback) 되었을 때 에러 로그에 기록하도록 트레이스 플래그(trace flag) 3412를 설정할 수도 있다.

 만약 데이터베이스가 복구되지 않고 백업한 것도 없다면 다음의 트레이스 플래그를 사용하여 복구 과정을 건너 뛸 수 있다. 단, 이렇게 하면 데이터베이스/데이터의 일관성이 깨질 수 있지만 다른 대안이 없는 경우에는 이 방법을 사용하되 반드시 필요한 객체를 BCP나 다른 툴을 사용하여 즉시 백업 받아야 한다.

3607 : 모든 데이터베이스의 자동 복구 생략
3608 : 마스터 데이터베이스를 제외한 모든 데이터베이스의 자동 복구 생략


그래도 데이터베이스를 사용할 수 없다면 – suspect라고 표시됨 – 다음의 명령을 실행하여 데이터베이스를 비상 모드(emergency mode)로 설정한다(먼저 수정작업을 허용해야 한다). 그 다음에 데이터베이스에 접속하여(SQL Server를 재기동할 필요 없음) 필요한 데이터를 백업 받으면 된다.

UPDATE master..sysdatabases SET status=-32768 WHERE name=’’

모든 방법이 실패하고 어떻게 해야 할 바를 모르겠다면 마이크로소프트 제품 지원 서비스(PSS)에 바로 전화하면 된다. 그들은 이와 같은 문제에 대비해서 1년 365일 24시간 내내 서비스를 제공하고 있으며 데이터 손실에 비하면 소요되는 비용은 무시 할 만 하다.

신고

'밥벌이' 카테고리의 다른 글

SQL Server I/O Basic  (0) 2010.10.11
read-ahead 미리읽기란?  (0) 2010.10.08
시스템이 복구중이라고 하고 시작되지 않을때  (0) 2010.10.07
sp_lock2  (4) 2010.10.06
주의대상 복구 suspect  (0) 2010.10.06
Statistics Strategy  (0) 2010.09.30
Posted by 보미아빠

sp_lock2

밥벌이 / 2010.10.06 16:26

 

 use master
 
go
 

if object_id('sp_lock2') is not null
  drop proc sp_lock2
 go
 
 
 

create proc sp_lock2
as
 
set nocount on
set transaction isolation level read uncommitted

-- CTRL - T 모드로 변경 하세요
-- 도구 > 옵션 > 결과 텍스트 > 글꼴 > 굴림체
 -- 마스터 에서 돌리세요
-- 최초 김민석
 -- SQL Server MVP 2006~2009
 -- by minsouk@hotmail.com
-- 수정 하만철
 -- 20100624 세션정보 추가 김민석
-- 20110826 세션정보 수정 김민석
-- 20120919 varchar(max) 변경 김민석

 


 

/**** object view 생성을 위로 올렸습니다~!! ****/
 

if object_id('dbo.v_objlist') is not null
 drop view v_objlist
 
declare @viewheader varchar(max), @viewbody varchar(max)
 select @viewheader ='' , @viewbody =''
 if object_id('v_objlist') is not null
drop view v_objlist
 set @viewheader = 'create view dbo.v_objlist as '
 select
@viewbody = @viewbody + 'union all select db_id('''+quotename(name)+''') dbid
  , name collate database_default name
, id
  from '+quotename(name)+'.dbo.sysobjects '+char(13)+char(10)
 from master.dbo.sysdatabases
where dbid > 4
 select @viewbody = stuff(@viewbody, 1,10, '')
 exec (@viewheader + @viewbody)
 
print @viewheader + @viewbody
 

 


 
print N'######################################################################'
 print N'세션정보'
 print N'######################################################################'
 
DECLARE @VERSION INT
SELECT @VERSION = SUBSTRING(CAST(SERVERPROPERTY('PRODUCTVERSION') AS VARCHAR(100))
  , 1, CHARINDEX('.',CAST(SERVERPROPERTY('PRODUCTVERSION') AS VARCHAR(100)))-1)
 
 
 
IF @VERSION >= 9 BEGIN
SELECT SESSION_ID
  , CASE TRANSACTION_ISOLATION_LEVEL
WHEN 0 THEN '지정되지 않음'
WHEN 1 THEN '커밋되지 않은 읽기'
 WHEN 2 THEN '커밋된 읽기'
 WHEN 3 THEN '##반복 읽기##'
 WHEN 4 THEN '@@직렬화 가능@@'
 WHEN 5 THEN 'XX스냅숏XX' ELSE '?' END
, *
FROM SYS.DM_EXEC_SESSIONS
  WHERE SESSION_ID > 50
 END


print N'######################################################################'
 print N'락인포 어뷰징 확인 200개 ver 0.1'
 print N'######################################################################'
 
select top 200
  rsc_text
  , count(*) cnt
  , case req_status
when 1 then N'허가됨'
 when 2 then N'변환중'
 when 3 then N'대기중'
  end req_status
  , max(left(db_name(rsc_dbid),30)+case when len(c.name) > 30 then '...' else '' end) dbname
, max(left(c.name,30)+case when len(c.name) > 30 then '...' else '' end) objname
, max(rsc_indid) IndId
  , max(case rsc_type
when 1 then null
  when 2 then 'DB'
  when 3 then 'File'
  when 4 then 'Index'
  when 5 then 'Table'
  when 6 then 'Page'
  when 7 then 'Key'
  when 8 then 'Extent'
  when 9 then 'RID'
  when 10 then 'App'
  end) Type
  , max(case req_mode --(0,3,6,7,8,9)
  when 0 then null
  when 1 then N'Sch-S:스키마 안전성'
 when 2 then N'Sch-M:스키마 수정'
 when 3 then N'S:공유'
 when 4 then N'U:업데이트'
 when 5 then N'X:단독'
 when 6 then N'IS:내재 공유'
 when 7 then N'IU:내재 업데이트'
 when 8 then N'IX:내재 단독'
 when 9 then N'SIU:공유 내재 업데이트'
 when 10 then N'SIX:공유 내재 단독'
 when 11 then N'UIX:업데이트 내재 단독'
 when 12 then N'BU:대량 작업'
 when 13 then N'RangeS_S:공유 키 범위 및 공유 리소스'
 when 14 then N'RangeS_U:공유 키 범위 및 업데이트 리소스'
 when 15 then N'RangeI_N:삽입 키 범위 및 Null 리소스'
 when 16 then N'RangeI_S:RangeI_N 및 S 잠금의 겹침으로 만들어진 키 범위 변환'
 when 17 then N'RangeI_U:RangeI_N 및 U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 18 then N'RangeI_X:RangeI_N 및 X 잠금의 겹침으로 만들어진 키 범위 변환'
 when 19 then N'RangeX_S:RangeI_N 및 RangeS_S. 잠금의 겹침으로 만들어진 키 범위 변환'
 when 20 then N'RangeX_U:RangeI_N 및 RangeS_U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 21 then N'RangeX_X:단독 키 범위 및 단독 리소스'
  end) Mode
  , max(case req_ownertype
when 1 then N'트랜잭션'
 when 2 then N'커서'
 when 3 then N'세션'
 when 4 then N'ExSession'
  end) req_ownertype
 from
master.dbo.syslockinfo a with (nolock)
  left join master.dbo.v_objlist c with (nolock)
  on c.dbid = a.rsc_dbid
  and c.id = a.rsc_objid
 where
req_spid <> @@spid
 -- and req_status = 1
  and rsc_type <> 2
group by req_status, rsc_text
 order by req_status, count(*) desc
 

/**** N' 추가했습니다~!! ****/
 print N'######################################################################'
 print N'헤드블럭만 보기 by minsouk@hotmail.com ver 0.1'
 print N'######################################################################'
 
select *
 from master.dbo.sysprocesses
where blocked = 0
and spid in (select blocked from master.dbo.sysprocesses where blocked <> 0)
 
print N'######################################################################'
 print N'헤드블럭 쿼리보기 by minsouk@hotmail.com ver 0.1'
 print N'######################################################################'
 
 
 
/**** adhoc 경우 dbid, objectid 가 null 이라 dbname 보여주기위해 dbid 추가 했습니다!! ****/
 declare cur_headblock cursor fast_forward
for
select spid, sql_handle, dbid
  from master.dbo.sysprocesses
where blocked = 0
and spid in (select blocked from master.dbo.sysprocesses where blocked <> 0)
 declare @spid varchar(6)
 declare @dbid int
 declare @handle varbinary(64);
 open cur_headblock
 fetch next from cur_headblock into @spid, @handle, @dbid
 while (@@fetch_status != -1)
 begin
  print '#########################'
  print 'dbcc inputbuffer for spid ' + @spid
print '#########################'
 
 /***** adhoc, proc 구분하고 objname 보게 바꿔봤습니다~!! ****/
  select case when fn.dbid is null then 'AdHoc' else 'Proc' end as qry_type, db_name(@dbid)
dbname, vo.name as objname, [text]
from ::fn_get_sql(@handle) fn
  left outer join v_objlist vo on fn.dbid = vo.dbid and fn.objectid = vo.id
  exec ('dbcc inputbuffer (' + @spid + ')')
  fetch next from cur_headblock into @spid, @handle, @dbid
 end
 deallocate cur_headblock
 
print N'######################################################################'
 print N'락트리 보기 by minsouk@hotmail.com ver 0.2'
 print N'######################################################################'
 
if object_id ('tempdb..#tbl_sysprocesses') is not null
  drop table #tbl_sysprocesses

create table #tbl_sysprocesses
 (
depth int
  , tree varchar(7000)
  , spid int
  , blocked int
  --, sql_handle varbinary(64)
 )
 
insert into #tbl_sysprocesses (depth, tree, spid, blocked)
select 0, cast(spid as varchar(100)) spid , spid, blocked
 from master.dbo.sysprocesses
where blocked = 0
and spid in (select blocked from master.dbo.sysprocesses where blocked <> 0)
 
declare @max_depth int
 set @max_depth = 5
 
while (1=1)
 begin
insert into #tbl_sysprocesses (depth, tree, spid, blocked)
select a.depth + 1 depth , a.tree + ' > ' +cast(b.spid as varchar(8000)) tree , b.spid, b.blocked
  from #tbl_sysprocesses a
  inner join master.dbo.sysprocesses b
  on a.spid = b.blocked
  where depth in (select max(depth) from #tbl_sysprocesses)
  and b.spid <> b.blocked
  if @@rowcount = 0 break
  set @max_depth = @max_depth - 1
  if @max_depth <= 1 break
end

declare @cnt varchar(10)
 select @cnt = cast(cnt as varchar(10)) from ( select count(*) cnt from sysprocesses where blocked <> 0 ) a
 
print N'######################################################################'
 print N'블럭카운트 : '+@cnt
print N'######################################################################'
 
select convert(char(10), cast((b.waittime / 1000) * 1.1574074074074073E-5 as datetime) , 108) as[hh:mm:ss]
  , left(a.tree, 40)+case when len(a.tree) > 40 then '...' else '' end locktree, b.*
 from #tbl_sysprocesses a
  inner join master.dbo.sysprocesses b
  on a.spid = b.spid
order by tree
 

print N'######################################################################'
 print N'######################################################################'
 print N'######################################################################'
 print N'락인포 보기 by minsouk@hotmail.com ver 0.5'
 print N'######################################################################'
 print N'######################################################################'
 print N'######################################################################'
 print N''
 
/*
 if object_id ('dbo.usp_create_v_objlist') is not null
 drop proc dbo.usp_create_v_objlist
 */
 
--exec dbo.usp_create_v_objlist
 
--set rowcount 200
 
print N'######################################################################'
 print N'락인포 허가 200개 exclude rsc_type db by minsouk@hotmail.com ver 0.6'
 print N'######################################################################'
 
select top 200
  req_spid spid
  , left(db_name(rsc_dbid),30)+case when len(c.name) > 30 then '...' else '' end dbname
, left(c.name,30)+case when len(c.name) > 30 then '...' else '' end objname
, rsc_indid IndId
  , case rsc_type
when 1 then null
  when 2 then 'DB'
  when 3 then 'File'
  when 4 then 'Index'
  when 5 then 'Table'
  when 6 then 'Page'
  when 7 then 'Key'
  when 8 then 'Extent'
  when 9 then 'RID'
  when 10 then 'App'
  end Type
  , rsc_type
  , rsc_text
  , case req_mode --(0,3,6,7,8,9)
  when 0 then null
  when 1 then N'Sch-S:스키마 안전성'
 when 2 then N'Sch-M:스키마 수정'
 when 3 then N'S:공유'
 when 4 then N'U:업데이트'
 when 5 then N'X:단독'
 when 6 then N'IS:내재 공유'
 when 7 then N'IU:내재 업데이트'
 when 8 then N'IX:내재 단독'
 when 9 then N'SIU:공유 내재 업데이트'
 when 10 then N'SIX:공유 내재 단독'
 when 11 then N'UIX:업데이트 내재 단독'
 when 12 then N'BU:대량 작업'
 when 13 then N'RangeS_S:공유 키 범위 및 공유 리소스'
 when 14 then N'RangeS_U:공유 키 범위 및 업데이트 리소스'
 when 15 then N'RangeI_N:삽입 키 범위 및 Null 리소스'
 when 16 then N'RangeI_S:RangeI_N 및 S 잠금의 겹침으로 만들어진 키 범위 변환'
 when 17 then N'RangeI_U:RangeI_N 및 U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 18 then N'RangeI_X:RangeI_N 및 X 잠금의 겹침으로 만들어진 키 범위 변환'
 when 19 then N'RangeX_S:RangeI_N 및 RangeS_S. 잠금의 겹침으로 만들어진 키 범위 변환'
 when 20 then N'RangeX_U:RangeI_N 및 RangeS_U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 21 then N'RangeX_X:단독 키 범위 및 단독 리소스'
  end Mode
  , req_mode
  , case req_status
when 1 then N'허가됨'
 when 2 then N'변환중'
 when 3 then N'대기중'
  end req_status
  , req_refcnt
, req_lifetime
, req_ecid [req_ecid (isParallel)]
  , case req_ownertype
when 1 then N'트랜잭션'
 when 2 then N'커서'
 when 3 then N'세션'
 when 4 then N'ExSession'
  end req_ownertype
  , req_transactionID
  , req_transactionUOW [req_transactionUOW (isDTC)]
 from
master.dbo.syslockinfo a with (nolock)
  left join master.dbo.v_objlist c with (nolock)
  on c.dbid = a.rsc_dbid
  and c.id = a.rsc_objid
 where
req_spid <> @@spid
  and req_status = 1
  and rsc_type <> 2
order by
spid -- 정렬
 
print N'######################################################################'
 print N'락인포 변환 200개 by minsouk@hotmail.com ver 0.5'
 print N'######################################################################'
 
select top 200
  req_spid spid
  , left(db_name(rsc_dbid),30)+case when len(c.name) > 30 then '...' else '' end dbname
, left(c.name,30)+case when len(c.name) > 30 then '...' else '' end objname
, rsc_indid IndId
  , case rsc_type
when 1 then null
  when 2 then 'DB'
  when 3 then 'File'
  when 4 then 'Index'
  when 5 then 'Table'
  when 6 then 'Page'
  when 7 then 'Key'
  when 8 then 'Extent'
  when 9 then 'RID'
  when 10 then 'App'
  end Type
  , rsc_type
  , rsc_text
  , case req_mode --(0,3,6,7,8,9)
  when 0 then null
  when 1 then N'Sch-S:스키마 안전성'
 when 2 then N'Sch-M:스키마 수정'
 when 3 then N'S:공유'
 when 4 then N'U:업데이트'
 when 5 then N'X:단독'
 when 6 then N'IS:내재 공유'
 when 7 then N'IU:내재 업데이트'
 when 8 then N'IX:내재 단독'
 when 9 then N'SIU:공유 내재 업데이트'
 when 10 then N'SIX:공유 내재 단독'
 when 11 then N'UIX:업데이트 내재 단독'
 when 12 then N'BU:대량 작업'
 when 13 then N'RangeS_S:공유 키 범위 및 공유 리소스'
 when 14 then N'RangeS_U:공유 키 범위 및 업데이트 리소스'
 when 15 then N'RangeI_N:삽입 키 범위 및 Null 리소스'
 when 16 then N'RangeI_S:RangeI_N 및 S 잠금의 겹침으로 만들어진 키 범위 변환'
 when 17 then N'RangeI_U:RangeI_N 및 U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 18 then N'RangeI_X:RangeI_N 및 X 잠금의 겹침으로 만들어진 키 범위 변환'
 when 19 then N'RangeX_S:RangeI_N 및 RangeS_S. 잠금의 겹침으로 만들어진 키 범위 변환'
 when 20 then N'RangeX_U:RangeI_N 및 RangeS_U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 21 then N'RangeX_X:단독 키 범위 및 단독 리소스'
  end Mode
  , req_mode
  , case req_status
when 1 then N'허가됨'
 when 2 then N'변환중'
 when 3 then N'대기중'
  end req_status
  , req_refcnt
, req_lifetime
, req_ecid [req_ecid (isParallel)]
  , case req_ownertype
when 1 then N'트랜잭션'
 when 2 then N'커서'
 when 3 then N'세션'
 when 4 then N'ExSession'
  end req_ownertype
  , req_transactionID
  , req_transactionUOW [req_transactionUOW (isDTC)]
 from
master.dbo.syslockinfo a with (nolock)
  left join master.dbo.v_objlist c with (nolock)
  on c.dbid = a.rsc_dbid
  and c.id = a.rsc_objid
 where
req_spid <> @@spid and req_status = 2
 order by
spid -- 정렬
 
print N'######################################################################'
 print N'락인포 대기 200개 by minsouk@hotmail.com ver 0.5'
 print N'######################################################################'
 
select top 200
  req_spid spid
  , left(db_name(rsc_dbid),30)+case when len(c.name) > 30 then '...' else '' end dbname
, left(c.name,30)+case when len(c.name) > 30 then '...' else '' end objname
, rsc_indid IndId
  , case rsc_type
when 1 then null
  when 2 then 'DB'
  when 3 then 'File'
  when 4 then 'Index'
  when 5 then 'Table'
  when 6 then 'Page'
  when 7 then 'Key'
  when 8 then 'Extent'
  when 9 then 'RID'
  when 10 then 'App'
  end Type
  , rsc_type
  , rsc_text
  , case req_mode --(0,3,6,7,8,9)
  when 0 then null
  when 1 then N'Sch-S:스키마 안전성'
 when 2 then N'Sch-M:스키마 수정'
 when 3 then N'S:공유'
 when 4 then N'U:업데이트'
 when 5 then N'X:단독'
 when 6 then N'IS:내재 공유'
 when 7 then N'IU:내재 업데이트'
 when 8 then N'IX:내재 단독'
 when 9 then N'SIU:공유 내재 업데이트'
 when 10 then N'SIX:공유 내재 단독'
 when 11 then N'UIX:업데이트 내재 단독'
 when 12 then N'BU:대량 작업'
 when 13 then N'RangeS_S:공유 키 범위 및 공유 리소스'
 when 14 then N'RangeS_U:공유 키 범위 및 업데이트 리소스'
 when 15 then N'RangeI_N:삽입 키 범위 및 Null 리소스'
 when 16 then N'RangeI_S:RangeI_N 및 S 잠금의 겹침으로 만들어진 키 범위 변환'
 when 17 then N'RangeI_U:RangeI_N 및 U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 18 then N'RangeI_X:RangeI_N 및 X 잠금의 겹침으로 만들어진 키 범위 변환'
 when 19 then N'RangeX_S:RangeI_N 및 RangeS_S. 잠금의 겹침으로 만들어진 키 범위 변환'
 when 20 then N'RangeX_U:RangeI_N 및 RangeS_U 잠금의 겹침으로 만들어진 키 범위 변환'
 when 21 then N'RangeX_X:단독 키 범위 및 단독 리소스'
  end Mode
  , req_mode
  , case req_status
when 1 then N'허가됨'
 when 2 then N'변환중'
 when 3 then N'대기중'
  end req_status
  , req_refcnt
, req_lifetime
, req_ecid [req_ecid (isParallel)]
  , case req_ownertype
when 1 then N'트랜잭션'
 when 2 then N'커서'
 when 3 then N'세션'
 when 4 then N'ExSession'
  end req_ownertype
  , req_transactionID
  , req_transactionUOW [req_transactionUOW (isDTC)]
 from
master.dbo.syslockinfo a with (nolock)
  left join master.dbo.v_objlist c with (nolock)
  on c.dbid = a.rsc_dbid
  and c.id = a.rsc_objid
 where
req_spid <> @@spid
  and req_status = 3
 order by
spid -- 정렬
 
set rowcount 0
 
print N'######################################################################'
 print N'블럭되는 쿼리보기 sql_handle 별 50개 by minsouk@hotmail.com ver 0.2'
 print N'######################################################################'
 
declare cur_blocked cursor fast_forward
for
select top 50 max(spid) spid, sql_handle, max(dbid) dbid from sysprocesses where blocked <> 0
group by sql_handle
 --declare @spid varchar(6)
 --declare @handle varbinary(64)
 open cur_blocked
 fetch next from cur_blocked into @spid, @handle, @dbid
 while (@@fetch_status != -1)
 begin
  print '|||||||||||||||||||||||||'
  print 'dbcc inputbuffer for spid ' + @spid
  print '|||||||||||||||||||||||||'
  select case when fn.dbid is null then 'AdHoc' else 'Proc' end as qry_type, db_name(@dbid)
dbname, vo.name as objname, [text]
from ::fn_get_sql(@handle) fn
  left outer join v_objlist vo on fn.dbid = vo.dbid and fn.objectid = vo.id
  exec ('dbcc inputbuffer (' + @spid + ')')
  fetch next from cur_blocked into @spid, @handle, @dbid
 end
 deallocate cur_blocked
 

go
 

exec dbo.sp_lock2
 
go

 

신고

'밥벌이' 카테고리의 다른 글

read-ahead 미리읽기란?  (0) 2010.10.08
시스템이 복구중이라고 하고 시작되지 않을때  (0) 2010.10.07
sp_lock2  (4) 2010.10.06
주의대상 복구 suspect  (0) 2010.10.06
Statistics Strategy  (0) 2010.09.30
CursorTypes, LockTypes, and CursorLocations  (2) 2010.09.30
Posted by 보미아빠
TAG lock

sql server 2000 suspect 해결

USE MASTER
GO
EXEC SP_CONFIGURE 'ALLOW UPDATES',1
GO
RECONFIGURE WITH OVERRIDE
GO

UPDATE SYSDATABASES SET STATUS=STATUS|32768
WHERE NAME ='DBNAME'

DBCC REBUILD_LOG('DBNAME', 'H:\MSSQL\DATA\DBNAME_LOG2.LDF')
DBCC CHECKDB('DBNAME')
DBCC CHECKDB('DBNAME', REPAIR_ALLOW_DATA_LOSS)

UPDATE SYSDATABASES SET STATUS=STATUS&~32768
WHERE NAME ='DBNAME'

EXEC SP_CONFIGURE 'ALLOW UPDATES',0
GO
RECONFIGURE WITH OVERRIDE
GO

sql server 2005 이상 suspect 해결

EXEC SP_RESETSTATUS 'DB';
ALTER DATABASE DB SET EMERGENCY
DBCC CHECKDB(DB)
ALTER DATABASE DB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CHECKDB ('DB', REPAIR_ALLOW_DATA_LOSS)
ALTER DATABASE DB SET MULTI_USER
신고

'밥벌이' 카테고리의 다른 글

read-ahead 미리읽기란?  (0) 2010.10.08
시스템이 복구중이라고 하고 시작되지 않을때  (0) 2010.10.07
sp_lock2  (4) 2010.10.06
주의대상 복구 suspect  (0) 2010.10.06
Statistics Strategy  (0) 2010.09.30
CursorTypes, LockTypes, and CursorLocations  (2) 2010.09.30
Posted by 보미아빠

불쌍한 서버들이 많아 이 글을 읽고, 혹시나 아직도 불쌍한 서버가 있다면, 꼭 구해 주세요 ~ (불쌍해.....ㅜ.ㅜ)

[2000 에서 확인 32bit without AWE]

dbcc memorystatus

 Dynamic Memory Manager         Buffers    
------------------------------ -----------
QueryPlan                      205678
205678 * 8 = 1645424  (한강으로 GoGo~)

[2005 에서 확인 32bit with AWE]

AWE Allocated                                                   5349376

CACHESTORE_OBJCP (Total)                                          KB

SinglePage Allocator                                            31280

CACHESTORE_SQLCP (Total)                                          KB

SinglePage Allocator                                            740208 KB(한강으로 GoGo~)

 

 

[2008 에서 확인 쿼리 64bit 24GB MaxMemory]

SELECT TOP(20) [TYPE], SUM(SINGLE_PAGES_KB) AS [SPA MEM, KB]

  FROM SYS.DM_OS_MEMORY_CLERKS

 GROUP BY [TYPE] 

  WITH ROLLUP

 ORDER BY SUM(SINGLE_PAGES_KB) DESC;

제일 상단의 총 합계가 얼마인가요?

 4GB 좀 넘어요?  역쉬 (한강으로 GoGo~)

SQL Server 2000 32bit 를 쓰고 있는데 플랜 메모리가 1.6GB 이다.

SQL Server 2000, 2005, 2008 32bit AWE를 쓰고 있는데 플랜 메모리가 700MB 이다.

SQL Server 2005 ~ 2008 64bit 쓰고 있는데, 플랜 메모리가 4GB 정도 되더라.

이럼 개발자랑 DBA 랑 두손 부여잡고 한강으로 가시길 바랍니다. (농담 입니다. ^^;;)

위 양은 쓸수 있는 최대양을 다 쓰고 있는 모습 입니다.

 

이런 서버들은 대부분 Plan Cache 를 재활용 하지 못하는 구조 입니다.

원인은 다양한데요, 

 

1.  top 절이 파라메터 바인딩 되지 못한다.

2. where 절 다음에 오는 predicate 가 파라메터 바인딩 되지 못한다.

3. dynamic sql 을 파라메터 바인딩 시키지 않고 그냥 exec (@sql) 로 돌린다.

4. 이외 영역의 이슈는 각 메모리 영역별로 리서치 해보시길 바랍니다.

 

등등의 이슈가 있습니다. (잘 튜닝된 서버의 플랜 캐시 메모리 사이즈는 100 MB를 넘지 않습니다. )

자기가 운영하는 서버가 이런 사황에  있다면,  빨리 고쳐 Memory / CPU / DISK Subsystem 을 보다 효율적으로 사용 할 수 있도록 고쳐 주세요 ~

 

더 상세한 내용은 다음을 참고 하세요

http://msdn.microsoft.com/en-us/library/ee343986.aspx



select
 type,
 sum(virtual_memory_reserved_kb) as [VM Reserved],
 sum(virtual_memory_committed_kb) as [VM Committed],
 sum(awe_allocated_kb) as [AWE Allocated],
 sum(shared_memory_reserved_kb) as [SM Reserved],
 sum(shared_memory_committed_kb) as [SM Committed],
 sum(multi_pages_kb) as [MultiPage Allocator],
 sum(single_pages_kb) as [SinlgePage Allocator]
from sys.dm_os_memory_clerks
group by type
order by 8 desc

 

 

select
  type,
  sum(virtual_memory_reserved_kb) as [VM Reserved],
  sum(virtual_memory_committed_kb) as [VM Committed],
  sum(awe_allocated_kb) as [AWE Allocated],
  sum(shared_memory_reserved_kb) as [SM Reserved],
  sum(shared_memory_committed_kb) as [SM Committed],
  sum(pages_kb) as [MultiPage Allocator]
 
 from sys.dm_os_memory_clerks
 group by type
 order by 7 desc

신고
Posted by 보미아빠

아래 스크립트는 비 효율적인 프로그램 디자인으로 인해 플랜이 무수히 생기는 과정을 시뮬레이션 하고
해당 플랜 서버에서 제거 하는 방법입니다.

1. 쿼리에서 처음부터 바인드 변수 처리
2. OPTION (RECOMPILE) 을 이용해 플랜이 생기지 않도록 처리
3. 생긴플랜 지우기 등을 생각해 볼 수 있을듯 합니다.

일단 sql 모니터링 프로그램이 죽어도 프로그램을 고쳐주지 않으므로 제거하는 방법을 생각해 보았습니다.

-- 테스트 테이블 만들기
SET NOCOUNT ON

IF OBJECT_ID('TBLX') IS NOT NULL
DROP TABLE TBLX
GO

CREATE TABLE TBLX
(IDX INT IDENTITY(1,1)
,C1 INT
)
GO

-- 데이터 삽입
INSERT INTO TBLX VALUES(1)
GO 10000

CREATE UNIQUE CLUSTERED INDEX UCL_TBLX ON TBLX (IDX)
GO

-- 비 효율적인 어플리케이션 시뮬레이션 (플랜 메모리 과도하게 사용 하도록)
DECLARE @MAX INT, @SQL_TEXT VARCHAR(8000)

SELECT @MAX = MAX(IDX) FROM TBLX
WHILE (@MAX > 0) BEGIN
 SET @SQL_TEXT = 'SELECT TOP 10 * FROM TBLX WHERE IDX ='+CAST(@MAX AS VARCHAR(100)) --+ 'OPTION (RECOMPILE)' -- 파라메터 바인딩이 되지 않도록 TOP 사용
 --PRINT @SQL_TEXT
 EXEC (@SQL_TEXT)
 SET @MAX -= 1
END
GO

-- 쓸모 없는 플랜을 제거
DECLARE @T_PLAN_HANDLE TABLE
(IDX INT IDENTITY(1,1)
,PLAN_HANDLE VARBINARY (1000))

INSERT INTO @T_PLAN_HANDLE
SELECT PLAN_HANDLE--, *
  FROM SYS.DM_EXEC_CACHED_PLANS
 CROSS APPLY SYS.DM_EXEC_SQL_TEXT(PLAN_HANDLE)
 WHERE USECOUNTS = 1
   AND OBJTYPE = 'ADHOC'
-- AND 기타조건 I모사 SQL 모니터링 쿼리?

DECLARE @MAX INT, @PLAN_HANDLE VARCHAR (1000), @SQL_TEXT VARCHAR(8000)
SELECT @MAX = MAX(IDX) FROM @T_PLAN_HANDLE

WHILE (@MAX > 0) BEGIN
 SELECT @PLAN_HANDLE = SYS.FN_SQLVARBASETOSTR( PLAN_HANDLE) FROM @T_PLAN_HANDLE WHERE IDX = @MAX
 SET @SQL_TEXT = 'DBCC FREEPROCCACHE ('+CAST(@PLAN_HANDLE AS VARCHAR(8000))+')'
 --PRINT @SQL_TEXT
 EXEC (@SQL_TEXT)
 SET @MAX -= 1
END

--DBCC MEMORYSTATUS
--******************************************************************************
--* AD-HOC 쿼리로 인해 PLAN MEMORY 영역이 비 효율적으로 사용되고 있는 상태
--******************************************************************************

CACHESTORE_SQLCP (NODE 0)                KB
---------------------------------------- -----------
VM RESERVED                              0
VM COMMITTED                             0
AWE ALLOCATED                            0
SM RESERVED                              0
SM COMMITTED                             0
SINGLEPAGE ALLOCATOR                     119232 -- 대충 넣다가 정지해서 이것보다 많은 메모리가 올라 갈 수 있습니다.
MULTIPAGE ALLOCATOR                      248

--******************************************************************************
--* 필요 없다고 판단되는 쿼리를 PLAN 에서 삭제하고 난 후의 상태
--******************************************************************************

CACHESTORE_SQLCP (NODE 0)                KB
---------------------------------------- -----------
VM RESERVED                              0
VM COMMITTED                             0
AWE ALLOCATED                            0
SM RESERVED                              0
SM COMMITTED                             0
SINGLEPAGE ALLOCATOR                     8240
MULTIPAGE ALLOCATOR                      248

 

신고
Posted by 보미아빠

Statistics Strategy

밥벌이 / 2010.09.30 19:05

문제

1. 잘 돌아가던 서버가 갑자기 CPU 100% 를 치면서 이상 현상을 보인다.
2. 갑자기 SQL Server 나 Application 서버가 Hang 이 된다. 
    프로파일러에는 EventSubClass Statistics changed 가 찍혀있다.

해결법

1. 문제의 쿼리를 찾아 힌트를 명시하고, 최적화 기반 recompile 을 막습니다.
2. statistics disable ! 최후의 선택. 이때는 컬럼이나 테이블 단위로 설정하는 것이 좋고 전체 데이터베이스에 적용하면 관리가 상당히 힘들어 집니다.

1. 플랜이 다른 쿼리찾기
SELECT *
  FROM (
    SELECT TOP 5 QUERY_HASH,  COUNT(*) CNT, MAX(SQL_HANDLE) SQL_HANDLE
      FROM SYS.DM_EXEC_QUERY_STATS  
  GROUP BY QUERY_HASH
  ORDER BY 2 DESC ) QS
 CROSS APPLY (
    SELECT TOP 1 *
      FROM SYS.DM_EXEC_SQL_TEXT(QS.SQL_HANDLE) ) ST

2. 힌트명시 (통계 히스토그램을 보면 특정값에만 이상하게 값이 편차가 매우 큰 값이 들어있고 실제로는 다른 값들과 유사한 개수의 데이터가 들어있는 경우 입니다. 한마디로 통계가 잘 못 측정된 경우 입니다.) 
   1. index join method 
   2. specify index name
   3. option (힌트나열, keepfixed plan, maxdop ....)

http://www.sql-server-performance.com/articles/per/asynchronous_statistics_p1.aspx

ALTER DATABASE AUTO_UPDATE_STATISTICS_ASYNC ON
ALTER DATABASE AUTO_UPDATE_STATISTICS_ASYNC OFF


Plan optimality-related recompilations: The Big Picture

문제는 영문 소개 자료를 보면 잘 나와 있고, 재미있는 질문이 있었습니다. DEVDDC (미국에서 큰 개발자 컨퍼런스)에서 SQL 개발자에게 질문 했습니다. 그럼 이 기능을 Default 로 off 한 이유는 무엇인가요? SQL 개발자는 하위 호환성을 위해서 off 로 설정되어 있는것 같다. 라고 설명 하더군요. 한마디로 off 할 이유가 없다는 것이죠.



ALTER DATABASE dbname
    SET AUTO_CREATE_STATISTICS ON;

SELECT name AS "Name",
    is_auto_create_stats_on AS "Auto Create Stats",
    is_auto_update_stats_on AS "Auto Update Stats",
    is_read_only AS "Read Only"
FROM sys.databases
WHERE database_ID > 4;

SELECT name AS "Name",
    is_auto_update_stats_async_on AS "Asynchronous Update"
FROM sys.databases;

다음으로 좋은 문서 링크 드립니다. 

http://technet.microsoft.com/en-us/library/cc966425.aspx

If any of the statistics are outdated, they are updated one-at-a-time. The query compilation waits for the updates to finish. An important difference between SQL Server 2000 and SQL Server 2005 regarding this step is that in SQL Server 2005, statistics may optionally be updated asynchronously. That is, the query compilation thread is not blocked by statistics updating threads. The compilation thread proceeds with stale statistics.
DB에 해당 옵션이 활성화 되어 있어야만 이렇게 됩니다.

Identifying statistics-related recompilations

Statistics-related recompilations can be identified by the "EventSubClass" column of the profiler trace (to be described later in this paper) containing the string "Statistics changed".

Closing remarks

An issue not directly related to the topic of this document is: given multiple statistics on the same set of columns in the same order, how does the query optimizer decide which ones to load during query optimization? The answer is not simple, but the query optimizer uses such guidelines as: Give preference to recent statistics over older statistics; Give preference to statistics computed using FULLSCAN option to those computed using sampling; and so on.

There is a potential of confusion regarding the "cause and effect" relationship between plan optimality-related compilations, recompilations, and statistics creation/updates. Recall that statistics can be created or updated manually or automatically. Only compilations and recompilations cause automatic creation or updates of statistics. On the other hand, when a statistic is created or updated (manually or automatically), there is an increased chance of recompilation of a query plan which might find that statistic "interesting."

Best practices

Four best practices for reducing plan optimality-related batch recompilations are given next:

Best Practice: Because a change in cardinality of a table variable does not cause recompilations, consider using a table variable instead of a temporary table. However, because the query optimizer does not keep track of a table variable's cardinality and because statistics are not created or maintained on table variables, non-optimal query plans might result. One has to experiment whether this is the case, and make an appropriate trade-off.

Best Practice: The KEEP PLAN query hint changes the recompilation thresholds for temporary tables, and makes them identical to those for permanent tables. Therefore, if changes to temporary tables are causing many recompilations, this query hint can be used. The hint can be specified using the following syntax:

SELECT B.col4, sum(A.col1) FROM dbo.PermTable A INNER JOIN #TempTable B ON A.col1 = B.col2 WHERE B.col3 < 100 GROUP BY B.col4 OPTION (KEEP PLAN)

Best Practice: To avoid recompilations due to plan optimality-related
(statistic update-related) reasons totally, KEEPFIXED PLAN query hint can be specified using the syntax:

SELECT c.TerritoryID, count(*) as Number, c.SalesPersonID FROM Sales.Store s INNER JOIN Sales.Customer c ON s.CustomerID = c.CustomerID WHERE s.Name LIKE '%Bike%' AND c.SalesPersonID > 285 GROUP BY c.TerritoryID, c.SalesPersonID ORDER BY Number DESC OPTION (KEEPFIXED PLAN)

With this option in effect, recompilations can only happen because of correctness-related reasons — for example, schema of a table referenced by a statement changes, or a table is marked with sp_recompile procedure.

In SQL Server 2005, there is a slight change in behavior as described below. Suppose that a query with OPTION(KEEPFIXED PLAN) hint is being compiled for the first time, and compilation causes auto-creation of a statistic. If SQL Server 2005 can get a special "stats lock," a recompilation happens and the statistic is auto-created. If the "stats lock" cannot be obtained, there is no recompilation, and the query is compiled without that statistic. In SQL Server 2000, a query with OPTION(KEEPFIXED PLAN) is never recompiled because of statistics-related reasons, and therefore, in this scenario, no attempt is made to get a "stats lock" or to auto-create the statistic.

Best Practice: Turning off automatic updates of statistics for indexes and statistics defined on a table or indexed view will ensure that plan optimality-related recompilations caused by those objects will stop. Note, however, that turning off the "auto-stats" feature using this method is usually not a good idea because the query optimizer is no longer sensitive to data changes in those objects, and sub-optimal query plans might result. Adopt this method only as a last resort after exhausting all of the other alternatives.

 
신고

'밥벌이' 카테고리의 다른 글

read-ahead 미리읽기란?  (0) 2010.10.08
시스템이 복구중이라고 하고 시작되지 않을때  (0) 2010.10.07
sp_lock2  (4) 2010.10.06
주의대상 복구 suspect  (0) 2010.10.06
Statistics Strategy  (0) 2010.09.30
CursorTypes, LockTypes, and CursorLocations  (2) 2010.09.30
Posted by 보미아빠
누가 ADO 에서 Cache Size 변화에 따른 로컬 Vs. 원격 IDC간 성능 차이를 알고 싶다고 의뢰해와서 테스트 해보게 되었습니다.

MySQL 은 adUseServer 를 지원하지 않습니다. SQL Server 는 둘 다 지원 합니다.
전 Test 해본 후에야 알았습니다. 역시 문서는 꼼꼼히 읽어봐야 하나 봅니다. MySQL 로 후딱 테스트 해보고 끝낼려고 하다가 반나절 넘게 고생하고 테스트 못할뻔...

아래는 Cache Size (Fetch Size 라고 적힌 부분 입니다.) 에 대한 성능 Test 곡선 입니다.
실험결과 16개이상에서는 성능상 별 이득이 없었습니다. 아래 글에서 마크한 부분이라도 읽어두시면 좋습니다.

붉은선은 Remote IDC 간 성능 곡선이고,
푸른색은 Local IDC 간 성능 곡선 입니다.



TEST 프로그램은 첨부파일로 담았으니 혹시 관심있는 분은 Test 해보시길 바랍니다.
VS2010 c# Console application 입니다.


마지막으로 당부 드리고 싶은말은 SQL Server 어플리케이션 성능이 좋지않아 원인을 분석해보니 ServerSide 커서를 사용하고 그 CacheSize 혹은 FetchSize 가 1로 되어 있다면, 이 CacheSize 만 늘이시길 바랍니다. 아니면, 어플리케이션 의도상 반드시 ServerSide 커서가 필요한 어플리케이션이 있을 수 있으니 주의해서 설정(튜닝) 하시길 바랍니다. 그냥 클라이언트 커서로 바꾸시구요, 에러나는건 잡으면서 반나절만 고생하시면 되요. 이럼 아니되옵니다.

원본글 링크 http://dev.mysql.com/tech-resources/articles/vb-cursors-and-locks.html

Introduction

One of the most common sources of trouble for the beginning VB / MySQL developer seems to revolve around which cursor location to use. Related to the cursor location problem is the choice of cursor type and lock type. The purpose of this article is to assist the Visual Basic developer in choosing the proper cursor location, cursor type, and lock type to use when programming Visual Basic (or VB) applications that use MySQL as a back-end database through ADO and Connector/ODBC (MyODBC).

This article will assume that the reader is using the MySQL RDBMS, but should apply to developers using other database management systems. For an overview of why MySQL is a good choice for Visual Basic developers, see the Why VB/MySQL article on this site. This sample requires the latest version of Connector/ODBC (MyODBC), available for download here (currently 3.51.06).

On the Visual Basic side, I recommend you have service pack 5 installed for VB, which you can download here. Additionally, the latest version of MDAC (Microsoft Data Access Components) should be installed, and can be found here (currently 2.7 SP1). Finally, this article applies to ADO 2.7 and VB6. It is not applicable to ADO.NET under VB.NET (Unless you reference ADODB in your project and use it for database access).

What Are Cursors?

In ADO, when we talk about cursors, we are essentially talking about a set of rows. When you execute a query that returns rows of data, such as SELECT * FROM mytable, the resulting data is handled using a cursor. A cursor can be located either on the client with the adUseClient argument, or on the server with the adUseServer argument. In addition, the are 4 types of cursor: adOpenForwardOnly, adOpenStatic, adOpenDynamic, and adOpenKeyset.

The different types and locations will be discussed in further detail below. Your choice of cursor type and cursor location will affect what you are able to do with the data you retrieve, and how changes made to the data by other users are reflected in your copy of the data.

Cursor Location

The ADODB.Connection object (the ADO object used to broker all data exchanges between the VB application and the MySQL server) has a property known as CursorLocation which is used to set/retrieve the cursor location that will be used by any recordset objects that access their data through the connection object.

The CursorLocation property can only be set while the connection is closed, and the property will be inherited by any recordset objects that access their data through the given connection object. Recordset objects can also explicitly set a cursorlocation different than the connection objects cursorlocation as long as it is set before the recordset is open. The two options available for this property are adUseClient and adUseServer, with adUseServer being the default property.

adUseServer

When using the adUseServer server-side cursorlocation, responsibility for handling the data generated by a query lies with the database server. MySQL itself does not support server-side cursors, so the data handling is actually done by the Connector / ODBC driver. The benefit of server-side cursors is that we gain access to the dynamic cursor type. This allows us to see any changes to the data that are made by other users in the data our application is accessing.

For example: let's say we are selling tickets to a concert with our application, we need to know that a given seat is available for sale in real-time to ensure we do not double-book the seat. With a server-side cursor, we can be sure that the data we are manipulating is the most current possible. In addition, we have the ability to lock the data we are working on as we edit it, to make sure our changes are going to be posted to the database successfully.

With a server-side cursor (adUseServer), we have access to the adOpenDynamic and adOpenForwardOnly cursor types, and all four of the recordset lock types, which will be discussed below.

It should be noted that using a server-side cursor, and the adOpenDynamic cursor in particular, will result in a significant performance loss, and should be avoided if at all possible. In addition, certain functionality, such as the RecordCount property of a Recordset and the GetChunk and Appendchunk function for handling BLOB data, will fail or return abnormal results when used with a server-side cursor.

adUseClient

Client-side cursors, specified with the adUseClient keyword, are handled internally by ADO. These cursors offer more functionality than their server-side counterparts, and also result in less load being placed on the server. Most advanced ADO functionality is designed for use with client-side cursors, and I personally use client-side cursors for all my applications (with one exception).

When using a client-side adUseClient cursor, only the adOpenStatic cursor is available, and we cannot use the adLockPessimistic lock type (see below).

Client-side cursors also help decrease load on our MySQL server, since with a static cursor data is sent to the client and then the server has no further communications with the client. This allows your server to scale a lot better than with server-side cursors.

Cursor Types

In addition to the two cursor locations, there are four cursor types, three of which are supported under Connector/ODBC:

  • adOpenStatic (Client-Side)
  • adOpenForwardOnly (Server-Side)
  • adOpenDynamic (Server-Side)

The different cursor types support different functionality and features, and I will now discuss each one in detail. The fourth cursor type, adOpenKeySet, is not currently supported by MySQL / MyODBC.

adOpenStatic

The static cursor is the only cursor type that is currently available when using adUseClient as your cursor location. With a static cursor, the server will send the result set to the client, after which there will be no further communication from the server to the client. The client may communicate with the server to send changes back to the server. This makes the static cursor more resource-intensive for the client and less resource-intensive for the server, as the result set is stored in the client's memory instead of the server's.

If a different client makes changes to the underlying data after the query results are sent, the original client will receive no notification of the change. A static cursor is bi-directional, meaning that your application can move forwards and backwards through the recordset. The following methods are available to a recordset using a static cursor and the adLockOptimistic lock type (more on lock types later):

  • AddNew
  • Delete
  • Find
  • MoveFirst
  • MovePrevious
  • MoveNext
  • MoveLast
  • Resync
  • Update
  • UpdateBatch

The static cursor will also show an accurate value for the RecordCount property of your recordset, and supports the getchunk and appendchunk methods for dealing with BLOB data. If you are having trouble with either of these problems, explicitly setting your connection's cursorlocation to adUseClient should solve them.

One handy feature of the static cursor is the ability to fetch data asynchronously. When data is fetched asynchronously., a separate thread is started to handle row retrieval, and your VB application can begin processing returned rows immediately. An in depth article on asynchronous data fetching is pending, but to activate this feature, simple use the adFetchAsync option during your recordset.open method call.

If you specify any cursor type other than adOpenStatic when opening a recordset with an adUseClient cursor location, it will be automatically converted to a static cursor.

adOpenForwardOnly

The adForwardOnly cursor type is the fastest performing cursortype, and also the most limited. The forward-only cursor does not support the RecordCount property, and does not support the MovePrevious methods of the recordset object.

The most efficient way to access data for display to the screen out output to a file is to use a adOpenForwardOnly cursor with a adLockReadOnly lock type when opening a recordset. This combination is often referred to as a Firehose Cursor. A firehose cursor bypasses a lot of handling code between the client and server and allows for very fast data access when moving sequentially through the resulting rows.

The following recordset methods are supported when using a forward-only cursor with an optimistic lock:

  • AddNew
  • Delete
  • Find
  • Update
  • UpdateBatch

In addition, the forward-only cursor type supports non-caching queries. While an asynchronous query allows data to be worked on immediately, it offers no memory benefits when accessing large resultsets, as all rows eventually wind up in memory, taxing system resources when accessing a large number of rows, or a medium number of rows when BLOB data is involved.

With MySQL and Connector/ODBC, we can specify option 1048576 in our connection string or check off the option "Don't Cache Results" in the ODBC manager in order to specify to the ODBC driver that it should only retrieve one row at a time from the server. With this option set, memory usage on the client is limited as only one row at a time is stored in memory. With every call to the recordset's MoveNext method, the previous row is discarded and the next row is queried from the server.

adOpenDynamic

While the forward-only cursor is the most efficient of the cursor types, the dynamic cursor, specified but adOpenDynamic, is the least efficient. Because of it's inefficiency, dynamic cursor support must be manually activated by using option 32 in your connection string, or by checking "Enable Dynamic Cursor" in the ODBC manager. Without this option enabled, any cursortype other than forward-only with be automatically converted to a static cursor, with it enabled, all cursor types other than forward-only will be converted to dynamic.

Why is a dynamic cursor so slow? As there is no native support for dynamic, server-side cursors in MySQL, every call to a row-moving method(MoveNext, MovePrevious, etc.) results in the Connector/ODBC driver converting your method call to a SQL query, posting the query, and returning the resulting row. This also means that for a dynamic cursor to work properly, your underlying table needs a primary key column to determine the next/previous row with. As such, dynamic cursors are not recommended unless absolutely necessary.

The dynamic cursor supports the following recordset methods when opened with a optimistic lock:

  • AddNew
  • Delete
  • Find
  • MoveFirst
  • MovePrevious
  • Update
  • UpdateBatch

While Dynamic cursors can be beneficial for multi-user applications, it is best to avoid them when possible, and work around multi-user issues when possible by calling the resync and requery methods when possible, and executing UPDATE queries that increment and decrement count values instead of using the recordset to do updates (i.e. rather than getting an inventory count in a recordset, incrementing it in VB, and doing a recordset.update, use the connection object to execute a query similar to UPDATE inventory SET count = count - 1 WHERE itemcode = 5)

Lock Types

While cursor locations and cursor types specify how our data is going to be handled, the lock type property specifies how we are going to lock the underlying data to protect any changes we make and ensure they are processed. There are four different lock types, and the locktype is set in the recordset object as part of the open method (it can also be set using the LockType property of the recordset object). The four locktypes are: adLockReadOnly (default), adLockOptimistic, adLockPessimistic, and adLockBatchOptimistic. All four locktypes are available to a server-side cursor, the adLockPessimistic locktype is unavailable to a client-side cursor.

adLockReadOnly

The default lock type is adLockReadOnly. A read-only lock is the most efficient when accessing data, as there is no checking for data changes and therefore no extra traffic between the client and server while loading records.

As the name implies, using a read-only lock will block you from making any changes to the table. If you find yourself with an error message like "Current recordset does not support updating", then you need to change away from the default adLockReadOnly lock type.

adLockOptimistic

An optimistic lock is used for modifications that either happen in a low-concurrency environment, or where having multiple users making changes to the same records is not a major concern. With an optimistic lock, the table or row locks will occur when the update method of the recordset object is called. This will ensure the change is successfully made, but will not prevent other users from changing the underlying data while you are modifying it in VB.

The adLockOptimistic lock type is typically your best choice when deciding on a table lock for a non-read-only situation. In almost all my applications, the only two lock types I use are adLockReadOnly and adLockOptimistic.

adLockBatchOptimistic

When using the adBatchOptimistic lock type, your changes will be cached locally until the recordset's UpdateBatch method is called. When UpdateBatch is called, all changes will be pushed to the server in a group. This can make the bulk insert of a large number of records more efficient. (Note: Calling ALTER TABLE mytable DISABLE KEYS before a large batch of inserts, followed by ALTER TABLE mytable ENABLE KEYS after the batch completes, can dramatically speed up the batch insert process, as MySQL can rebuild an index faster than it can add one entry at a time).

adLockPessimistic

In a situation of high concurrency, with multiple users modifying the same data, you may need a pessimistic lock type. With asLockPessimistic, the underlying rows (or table) will be locked as soon as you begin making changes to the current record, and will not be unlocked until the Update method is called.

While this will ensure that you do not have overlapping changed with other users, it could cause performance issues, especially with a MyISAM table, with features table-level locking only. Make sure that the changes are immediately followed by the recordset's update method, and that there is no break for user input between a change and the update in order to ensure no long breaks (and potentially canceled locks by the database) in the operation of the database.

While adLockPessimistic has it's place, the same advice I gave regarding dynamic cursors applies: avoid it when possible, as it is very resource intensive and involves a lot more work both on the client and server side.

Conclusion

While there are a large number of potential CursorType/CursorLocation combinations, the ones that are currently available to the MySQL/VB developer are: adUseClient/adOpenStatic, adUseServer/adOpenForwardOnly, and adUseServer/adOpenDynamic.

For most uses, adUseClient/adOpenStatic is your best choice, with adLockReadOnly as your lock type for any read-only operations (export to a file, load rows to a listview, combobox, etc.) and adLockOptimistic as your lock type for any read/write operations.

adOpenDynamic and adLockPessimistic are best suited for high-concurrency situations where you need to ensure that multiple users do not corrupt each other's data. While these offer the most current views of data and the most restrictive locking, they do so at a severe price as far as performance is concerned.

The combination of adUseServer/adOpenForwardOnly/adLockReadonly offers the best performance overall for operations like populating controls and exporting to files. When combined with option 1048576 (Don't cache query results), adOpenForwardOnly also provides excellent memory efficiency, as only one record at a time is loaded into memory. Be awate that if a locktype other than adLockReadOnly is used, memory usage will slowly build as rows are loaded into memory and kept in case they are needed for an update or cancel statement. The one row at a time operation is only present with an adLockReadOnly/adOpenForwardOnly combination.

신고

'밥벌이' 카테고리의 다른 글

read-ahead 미리읽기란?  (0) 2010.10.08
시스템이 복구중이라고 하고 시작되지 않을때  (0) 2010.10.07
sp_lock2  (4) 2010.10.06
주의대상 복구 suspect  (0) 2010.10.06
Statistics Strategy  (0) 2010.09.30
CursorTypes, LockTypes, and CursorLocations  (2) 2010.09.30
Posted by 보미아빠

최근에 달린 댓글

최근에 받은 트랙백

글 보관함