<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results for 'app:weblogs' matching tag 'SQL Server'</title><link>http://msmvps.com/search/SearchResults.aspx?q=app:weblogs&amp;tag=SQL+Server&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tag 'SQL Server'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>SQL Server upgrade practices - choose optimal upgrade options</title><link>/http://sqlserver-qa.net/blogs/replication/archive/2009/10/26/6070.aspx</link><pubDate>Mon, 26 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1735343</guid><dc:creator>Anonymous</dc:creator><description>SQL Server Upgrade task needs a thorough planning and testing before you deploy the process in production environment. In this regard when performing an upgrade to a replicated environment, DBAs must make sure that all changes have been applied to all the databases that are involved in the replication topology before they attempt the upgrade. If your application databases are not involved in Replication procedures then you can proceed as per your pre-planning process. IN any case all the attributes...(&lt;a href="http://sqlserver-qa.net/blogs/replication/archive/2009/10/26/6070.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlserver-qa.net/aggbug.aspx?PostID=6070" width="1" height="1" alt="" /&gt;</description></item><item><title>Build an effiective Disaster Recovery solution for SQL Server Reporting Services</title><link>/http://sqlserver-qa.net/blogs/bi/archive/2009/10/24/build-an-effiective-disaster-recovery-solution-for-sql-server-reporting-services.aspx</link><pubDate>Sat, 24 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1734856</guid><dc:creator>Anonymous</dc:creator><description>As a Systems Administrator/DBA or even as an user have you ever realised &amp;quot;What is your data worth to you?&amp;quot; If so then an important aspect of data recovery solution is a required step, whatever is the application or system you use data access methods including a disaster recovery plan is essential to ensure your data’s security after a catastrophic event. It is incredibly expensive to retrieve data from failed hard drives, and not always possible. You may expect or no doubt that this blog states on...(&lt;a href="http://sqlserver-qa.net/blogs/bi/archive/2009/10/24/build-an-effiective-disaster-recovery-solution-for-sql-server-reporting-services.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlserver-qa.net/aggbug.aspx?PostID=6057" width="1" height="1" alt="" /&gt;</description></item><item><title>HDD DEAD?!</title><link>http://msmvps.com/blogs/gladchenko/archive/2009/10/20/1733661.aspx</link><pubDate>Tue, 20 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1733661</guid><dc:creator>gladchenko</dc:creator><description>&lt;p&gt;
&lt;div align="right"&gt;&lt;em&gt;&amp;hellip;и наконец моё любопытство возобладало, и я решил таки заглянуть, что же такого понаделел HP в TPC-H&amp;hellip;&lt;/em&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;div align="justify"&gt;
&lt;p align="justify"&gt;Не удивляйтесь, но поначалу я не предавал особого значения появляющимся с завидной регулярностью (раз в месяц) новым, ничем с виду не примечательным результатам. Но, когда появился третий из них, я заметил тенденцию, что они становятся с каждым разом немного ХУЖЕ и ДОРОЖЕ. Именно тогда мне стало любопытно, в чём там &amp;quot;порылась собака&amp;quot;&amp;hellip;&lt;br /&gt;Конечно, виною всему было то, как представлены результаты в сводной таблице: &lt;a href="http://www.tpc.org/tpch/results/tpch_results.asp?print=false&amp;amp;orderby=submitted&amp;amp;version=2%25&amp;amp;sortby=desc"&gt;Complete TPC-H Results List - Sorted by Date Submitted&lt;/a&gt;&lt;br /&gt;Просто, в представлении на сайте не видно главного изменения, поскольку испокон веков эта составляющая была неизменной и только в последние год - два ситуация начала выправляться к лучшему. На самом деле, HP в последнем из трёх своих результатов показал, как SAS диски могут оказаться более дорогим решением, чем SSD диски, при близкой производительности.&lt;br /&gt;Вот несколько видоизменённое представление результатов, с детализацией по конфигурации дисковой подсистемы:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://msmvps.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/gladchenko/4278.HP_2D00_TPC_2D00_H_2D00_SSD.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Ссылки на подробные описания тестов:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;
&lt;li&gt;&lt;a href="http://www.tpc.org/tpch/results/tpch_result_detail.asp?id=109100801"&gt;10/07/09 HP ProLiant DL380 G6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.tpc.org/tpch/results/tpch_result_detail.asp?id=109090801"&gt;09/04/09 HP ProLiant DL380 G6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.tpc.org/tpch/results/tpch_result_detail.asp?id=109082801"&gt;08/27/09 HP ProLiant DL380 G6&lt;/a&gt;&lt;/li&gt;
&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Результаты потрясающие! Оказывается решение на базе SSD получается чуть ли не в двое дешевле, чем на привычных нам SAS.&lt;br /&gt;Похоже, гегемонии производителей жёстких дисков приходит долгожданный конец, а точнее, последний рудимент зари IBM PC, этот кошмарный механический монстр, самое слабое звено любого компьютера - HDD может уйти в небытие!&lt;/p&gt;
&lt;/div&gt;</description></item><item><title>Finding out problamatic data in Bulk Insert data truncation error </title><link>/http://sqlserver-qa.net/blogs/t-sql/archive/2009/10/19/6047.aspx</link><pubDate>Mon, 19 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1733326</guid><dc:creator>Anonymous</dc:creator><description>Suppose you want to import data from a text file to a table, one of the options is to use Bulk Insert command It allows to import data to the table, though one/more columns don&amp;#39;t have enough size to get the maximum length of data from text file.It throws errors about data truncation with line numbers. What if you want to find out the rows from the text file that are not imported Here is a way Consider the following example --Create a testing table create table bulk_test ( test_no int , test_name...(&lt;a href="http://sqlserver-qa.net/blogs/t-sql/archive/2009/10/19/6047.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlserver-qa.net/aggbug.aspx?PostID=6047" width="1" height="1" alt="" /&gt;</description></item><item><title>How SQL Server 2008 can help to build fast track data warehouse?</title><link>/http://sqlserver-qa.net/blogs/bi/archive/2009/10/09/how-sql-server-2008-can-help-to-build-fast-track-data-warehouse.aspx</link><pubDate>Fri, 09 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1731037</guid><dc:creator>Anonymous</dc:creator><description>Beginning of this year I have posted here about Build your BI skills in fast track data warehouse and based on that I have had few questions and feedback on how best we can take help of SQL Server 2008 features to build the fast track data warehouse. Based on the material and resources available on Microsoft site the approach must be on data access layer, configuration (hardware, software) and maintaining the normalization practices.When you talk about Business Intelligence then data access layer...(&lt;a href="http://sqlserver-qa.net/blogs/bi/archive/2009/10/09/how-sql-server-2008-can-help-to-build-fast-track-data-warehouse.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlserver-qa.net/aggbug.aspx?PostID=5960" width="1" height="1" alt="" /&gt;</description></item><item><title>Tips for DBA: Замена для стандартного &amp;quot;Back Up Database Task&amp;quot;</title><link>http://msmvps.com/blogs/gladchenko/archive/2009/10/07/1730580.aspx</link><pubDate>Wed, 07 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1730580</guid><dc:creator>gladchenko</dc:creator><description>&lt;div align="justify"&gt;&lt;img src="http://www.itcommunity.ru/Themes/default/RssImportImages/588/13895ef4-2f7e-468e-b724-1a96b04270cd.gif" align="right" alt="" /&gt;
&lt;p align="justify"&gt;Очень часто получается так, что реальные бизнес -требования оказываются сложнее, чем возможности мастеров программного инструментария, поставляемого разными производителями ПО для задач администрирования SQL Server 2008. Например, недавно мне стало недостаточно гибкости &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms189036.aspx"&gt;мастера создания задачи резервного копирования&lt;/a&gt; базы данных для стандартного &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms187658.aspx"&gt;плана обслуживания&lt;/a&gt; БД. У меня возникла необходимость делать копию в несколько фалов на разных дисковых массивах и поддерживать хронологию копий по единым правилам. В несколько файлов выполнять резервное копирование бывает необходимо для повышения производительности этой операции, например, как это рекомендовано в этой статье: &amp;quot;&lt;a href="http://sqlcat.com/whitepapers/archive/2009/08/13/a-technical-case-study-fast-and-reliable-backup-and-restore-of-a-vldb-over-the-network.aspx"&gt;A Technical Case Study: Fast and Reliable Backup and Restore of Multi-Terabytes Database over the Network&lt;/a&gt;&amp;quot;.&lt;br /&gt;Мастер SSMS может либо поддерживать хронологию для одного файла копий, либо копировать в фиксированные имена нескольких указанных файлов. К счастью, совершенно не составляет труда заменить задачу резервного копирования на задачу исполнения сценария T-SQL, в котором выполнить нужную работу. Ниже представлен соответствующий шаблон сценария, взяв который за основу можно составить необходимую задачу исполнения сценария T-SQL.&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @path &lt;span style="color:#0000ff;"&gt;varchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;128&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @DBName &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;4000&lt;/b&gt;&lt;/span&gt;) = &lt;span style="color:#ff0000;"&gt;&amp;#39;&lt;big&gt;&lt;b&gt;ИМЯБАЗЫДАННЫХ&lt;/b&gt;&lt;/big&gt;&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @File1 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;4000&lt;/b&gt;&lt;/span&gt;), @File2 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;4000&lt;/b&gt;&lt;/span&gt;), @File3 &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;4000&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#008080;"&gt;-- Если диск для копий один, и он корректно задан, узнать путь к папке копий можно так:&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;EXEC&lt;/span&gt; master..xp_regread &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@rootkey=&lt;span style="color:#ff0000;"&gt;&amp;#39;HKEY_LOCAL_MACHINE&amp;#39;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@key=&lt;span style="color:#ff0000;"&gt;&amp;#39;SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer&amp;#39;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@value_name=&lt;span style="color:#ff0000;"&gt;&amp;#39;BackupDirectory&amp;#39;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@value=@path &lt;span style="color:#0000ff;"&gt;OUTPUT&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008080;"&gt;-- Формируем часть имени файла, в которой фиксируется имя БД и время создания копии&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;DECLARE&lt;/span&gt; @FileName &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;4000&lt;/b&gt;&lt;/span&gt;) = @path + &lt;span style="color:#ff0000;"&gt;&amp;#39;\&amp;#39;&lt;/span&gt; + @DBName +&lt;span style="color:#ff0000;"&gt;&amp;#39;\&amp;#39;&lt;/span&gt; + @DBName + &lt;span style="color:#ff0000;"&gt;&amp;#39;_&amp;#39;&lt;/span&gt; + &lt;span style="color:#ff0000;"&gt;&amp;#39;backup_&amp;#39;&lt;/span&gt; +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ff00ff;"&gt;CONVERT&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/span&gt;),YEAR(&lt;span style="color:#ff00ff;"&gt;CURRENT_TIMESTAMP&lt;/span&gt;), &lt;span style="color:#00008b;"&gt;&lt;b&gt;112&lt;/b&gt;&lt;/span&gt; ) + &lt;span style="color:#ff0000;"&gt;&amp;#39;_&amp;#39;&lt;/span&gt; +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ff00ff;"&gt;CASE&lt;/span&gt; &lt;span style="color:#ff00ff;"&gt;MONTH&lt;/span&gt;(&lt;span style="color:#ff00ff;"&gt;CURRENT_TIMESTAMP&lt;/span&gt;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;01&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;02&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;03&amp;#39;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;04&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;05&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;06&amp;#39;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;07&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;8&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;08&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;09&amp;#39;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;ELSE&lt;/span&gt; &lt;span style="color:#ff00ff;"&gt;CONVERT&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;),MONTH(&lt;span style="color:#ff00ff;"&gt;CURRENT_TIMESTAMP&lt;/span&gt;), &lt;span style="color:#00008b;"&gt;&lt;b&gt;112&lt;/b&gt;&lt;/span&gt; ) &lt;span style="color:#0000ff;"&gt;END&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ &lt;span style="color:#ff0000;"&gt;&amp;#39;_&amp;#39;&lt;/span&gt; +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ff00ff;"&gt;CASE&lt;/span&gt; &lt;span style="color:#ff00ff;"&gt;DAY&lt;/span&gt;(&lt;span style="color:#ff00ff;"&gt;CURRENT_TIMESTAMP&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;01&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;02&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;03&amp;#39;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;04&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;5&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;05&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;6&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;06&amp;#39;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;07&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;8&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;08&amp;#39;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;WHEN&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;9&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;THEN&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;09&amp;#39;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;ELSE&lt;/span&gt; &lt;span style="color:#ff00ff;"&gt;CONVERT&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;),DAY(&lt;span style="color:#ff00ff;"&gt;CURRENT_TIMESTAMP&lt;/span&gt;), &lt;span style="color:#00008b;"&gt;&lt;b&gt;112&lt;/b&gt;&lt;/span&gt; ) &lt;span style="color:#0000ff;"&gt;END&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+ &lt;span style="color:#ff0000;"&gt;&amp;#39;_&amp;#39;&lt;/span&gt; +&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ff00ff;"&gt;REPLACE&lt;/span&gt;(&lt;span style="color:#ff00ff;"&gt;REPLACE&lt;/span&gt;(&lt;span style="color:#ff00ff;"&gt;CAST&lt;/span&gt;(&lt;span style="color:#ff00ff;"&gt;CONVERT&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;time&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;7&lt;/b&gt;&lt;/span&gt;),CURRENT_TIMESTAMP, &lt;span style="color:#00008b;"&gt;&lt;b&gt;109&lt;/b&gt;&lt;/span&gt; ) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;nvarchar&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;14&lt;/b&gt;&lt;/span&gt;)),&lt;span style="color:#ff0000;"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;&amp;#39;&amp;#39;&lt;/span&gt;),&lt;span style="color:#ff0000;"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;,&lt;span style="color:#ff0000;"&gt;&amp;#39;_&amp;#39;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:#008080;"&gt;-- Добавляем к пути и имени файла идентификаторы и расширения &lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; @File1 = @FileName + + &lt;span style="color:#ff0000;"&gt;&amp;#39;01.bak&amp;#39;&lt;/span&gt;, @File2 = @FileName + + &lt;span style="color:#ff0000;"&gt;&amp;#39;02.bak&amp;#39;&lt;/span&gt;, @File3 = @FileName + + &lt;span style="color:#ff0000;"&gt;&amp;#39;03.bak&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008080;"&gt;-- Запускаем резервное копирование в три файла.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;BACKUP&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;DATABASE&lt;/span&gt; [&lt;span style="color:#ff0000;"&gt;&lt;b&gt;&lt;big&gt;ИМЯБАЗЫДАННЫХ&lt;/big&gt;&lt;/b&gt;&lt;/span&gt;] &lt;span style="color:#0000ff;"&gt;TO&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;DISK&lt;/span&gt; = @File1,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;DISK&lt;/span&gt; = @File2,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#0000ff;"&gt;DISK&lt;/span&gt; = @File3&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WITH&lt;/span&gt; NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, COMPRESSION, &lt;span style="color:#0000ff;"&gt;STATS&lt;/span&gt; = &lt;span style="color:#00008b;"&gt;&lt;b&gt;10&lt;/b&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;/div&gt;</description></item><item><title>Индексные объединения</title><link>http://msmvps.com/blogs/irinanaumova/archive/2009/10/02/1728973.aspx</link><pubDate>Fri, 02 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1728973</guid><dc:creator>IrinaNaumova</dc:creator><description>&lt;div align="justify"&gt;&lt;img src="https://msmvps.com:443/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/gladchenko/7357.Concatenation.jpg" align="right" alt="" /&gt;
&lt;p align="justify"&gt;По материалам статьи Craig Freedman: &lt;a href="http://blogs.msdn.com/craigfr/archive/2006/10/18/index-union.aspx"&gt;Index Union&lt;/a&gt;&lt;br /&gt;Перевод &lt;a href="https://msmvps.com:443/blogs/irinanaumova/default.aspx"&gt;Ирины Наумовой&lt;/a&gt;&lt;/p&gt;
&lt;p align="justify"&gt;&lt;a href="http://www.sql.ru/articles/mssql/2007/070604IntroductionToParallelQueryExecution.shtml"&gt;Ранее&lt;/a&gt; я планировал продолжить писать о параллелизме (и сделаю это в следующий раз в другой статье), но получил интересный вопрос и решил написать об индексных объединениях.&lt;/p&gt;
&lt;p&gt;Начнем:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;create&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;table&lt;/span&gt; T (a &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;, b &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;, c &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;, x &lt;span style="color:#0000ff;"&gt;char&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;200&lt;/b&gt;&lt;/span&gt;))&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;create&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;unique&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;clustered&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;index&lt;/span&gt; Ta &lt;span style="color:#0000ff;"&gt;on&lt;/span&gt; T(a)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;create&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;index&lt;/span&gt; Tb &lt;span style="color:#0000ff;"&gt;on&lt;/span&gt; T(b)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;create&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;index&lt;/span&gt; Tc &lt;span style="color:#0000ff;"&gt;on&lt;/span&gt; T(c)&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;insert&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;insert&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;insert&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;values&lt;/span&gt; (&lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;, &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Index Seek(OBJECT:([ Т ].[ Тb ]), SEEK:([ Т ]. [ b ]=(1) OR [ Т ]. [ b ]=(3)) ORDERED FORWARD)&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p align="justify"&gt;У нас имеется индекс на поле &amp;quot;b&amp;quot;, и, как и ожидалось, оптимизатор выбирает поиск по индексу. Поскольку мы имеем два предиката для поля &amp;quot;b&amp;quot;, мы получим поиск с двумя предикатами. Вначале выполнится предикат &amp;quot;b=1&amp;quot;, а зетем &amp;quot;b=3&amp;quot;. Обратите внимание, что поскольку мы выводим столбец &amp;quot;a&amp;quot;, а он является кластеризованным (и таким образом покрывает все некластеризованные индексы), не возникает необходимости в операции &lt;a href="http://www.sql.ru/articles/mssql/2006/121502BookmarkLookup.shtml"&gt;BOOKMARK LOOKUP (поиск закладок)&lt;/a&gt;. Пока нет никаких неожиданностей.&lt;br /&gt;Обратите внимание, что мы могли записать этот запрос в ином виде:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;union&lt;/span&gt; &lt;span style="color:#777777;"&gt;all&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Concatenation&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([ Т ].[ Тb ]), SEEK:([ Т ]. [ b ]=(1)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([ Т ].[ Тb ]), SEEK:([ Т ]. [ b ]=(3)) ORDERED FORWARD)&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Оптимизатор не объединяет эти операции в одну операцию &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms190400.aspx"&gt;INDEX SEEK (поиска по индексу)&lt;/a&gt;, но запросы и планы логически идентичны.&lt;br /&gt;Рассмотрим следующий запрос:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; c &amp;lt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Clustered Index Scan(OBJECT:([Т].[Тa]), WHERE:([ Т ]. [ b ]=(1) OR [Т]. [ c ]&amp;lt;(3)))&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p align="justify"&gt;У нас имеются индексы на столбцах &amp;quot;b&amp;quot; и &amp;quot;c&amp;quot;, но оптимизатор их не использовал. Почему? Нам нужны все строки, удовлетворяющие любому из предикатов. Мы могли бы использовать индекс на столбце &amp;quot;b&amp;quot;, чтобы получить строки, удовлетворяющие предикату &amp;quot;b=1&amp;quot;, но при этом мы можем пропустить строки, которые удовлетворяют предикату &amp;quot;с&amp;lt;3&amp;quot;, и для которых &amp;quot;b!=1&amp;quot;. Например, мы пропустили бы строку со значением (2,2,2,2). Та же самая проблема возникает при использовании индекса на столбце &amp;quot;с&amp;quot;, чтобы удовлетворить предикату &amp;quot;c&amp;lt;3&amp;quot;. (В моем примере данные не включают строк со значением &amp;quot;b=1&amp;quot;, для которых выполняется предикат &amp;quot;с&amp;gt;3&amp;quot;, но такая строка могла бы существовать, поэтому мы должны предусмотреть и такой вариант).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Индексные объединения&lt;/b&gt;&lt;/p&gt;
&lt;p align="justify"&gt;И так, давайте разберёмся, будет ли SQL Server так выполнять декомпозицию запроса, чтобы использовать два индекса? Да! Сначала для того чтобы оптимизатор выбрал другой план, в котором не будет сканирования кластерного индекса, мы должны добавить достаточно большое количество данных в таблицу, чтобы сделать операцию сканирования кластерного индекса более дорогостоящей.&lt;br /&gt;Обратите внимание, что к используемой ранее таблице я добавил столбец типа char(200), чтобы строки стали больше. Добавление этого столбца приведет к тому, что таблица будет занимать больше страниц, что также сделает операцию просмотра более дорогостоящей.&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;truncate&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;table&lt;/span&gt; T&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;nocount&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;on&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;declare&lt;/span&gt; @i &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; @i = &lt;span style="color:#00008b;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; @i &amp;lt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;1000&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;begin&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;insert&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;values&lt;/span&gt;(@i, @i, @i, @i)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt; @i = @i + &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; c &amp;lt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Sort(DISTINCT ORDER BY:([T]. [ а ]ASC))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Concatenation&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([T].[Tb]), SEEK:([T]. [ b ]=(1)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([T].[Tc]), SEEK:([T]. [ c ] &amp;lt; (3)) ORDERED FORWARD)&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Этот план очень похож на приведенный выше план с оператором UNION ALL. Оптимизатор выполнил декомпозицию таким образом, что запрос стал выглядеть так:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;union&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; c &amp;lt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Однако, стоит обратить внимание на то, что два объединяемых запроса могут возвратить дубликаты строк, поэтому нужно использовать оператор UNION (который устраняет дубликаты), а не UNION ALL (который этого не делает). Оператор &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms187919.aspx"&gt;CONCATENATION&lt;/a&gt; реализует конструкцию UNION ALL, а &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms186318.aspx"&gt;SORT DISTINCT&lt;/a&gt; устраняет дубликаты, превращая UNION ALL в UNION. Такой тип плана исполнения запроса можно считать индексным объединением.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Merge Join&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Давайте немного изменим запрос:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; c = &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Stream Aggregate(GROUP BY:([Т]. [ a ]))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Merge Join(Concatenation)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([ Т ].[ Тb ]), SEEK:([ Т ]. [ b ]=(1)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([Т].[Тc]), SEEK:([Т]. [ c ]=(3)) ORDERED FORWARD)&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Теперь, вместо операторов CONCATENATION и SORT DISTINCT мы имеем MERGE JOIN (Concatenation) и STREAM AGGREGATE. Что же произошло? MERGE JOIN (Concatenation) или &amp;quot;MERGE UNION&amp;quot; в действительности ничего не соединяют. Это осуществляется также, как с помощью итератора MERGE UNION, но в действительности выполняется операция UNION ALL с сохранением порядка входных строк. После этого используется STREAM AGGREGATE, который устраняет дубликаты (для получения более подробной информации, изучите статью &amp;quot;&lt;a href="http://www.sql.ru/articles/mssql/2007/070602StreamAggregate.shtml"&gt;Агрегат потока (Stream Aggregate)&lt;/a&gt;&amp;quot;, в которой написано об использовании STREAM AGGREGATE для устранения дубликатов). Такой план исполнения запроса будет работать лучше, потому что не будет использовать SORT DISTINCT, который использует память и может стать причиной сброса страницы данных на диск, если действие выполняется за пределами памяти. В этом плане исполнения запроса используется STREAM AGGREGATE, который память не использует.&lt;/p&gt;
&lt;p align="justify"&gt;Тогда почему же мы не использовали этот план с самого начала? Точно так же как &lt;a href="http://www.sql.ru/articles/mssql/2007/070602StreamAggregate.shtml"&gt;MERGE JOIN&lt;/a&gt;, MERGE UNION требует, чтобы входные данные были отсортированы по ключу слияния (в нашем случае это столбец &amp;quot;a&amp;quot;). Некластеризованный индекс &amp;quot;Tb&amp;quot; покрывает ключ индекса &amp;quot;b&amp;quot; и ключ кластеризованного индекса &amp;quot;a&amp;quot;. Таким образом, этот индекс возвращает строки в порядке (b, a). Однако, это эквивалентно предикату &amp;quot;b = 1&amp;quot;, столбец &amp;quot;b&amp;quot; - константа, этим мы фактически упорядочиваем строки по столбцу &amp;quot;a&amp;quot;. То же самое случается с индексом Tc и предикатом &amp;quot;c = 3&amp;quot;. Таким образом, у нас имеется два входных потока, которые оба упорядочены по столбцу &amp;quot;а&amp;quot;, и мы можем использовать MERGE UNION.&lt;br /&gt;В предшествующем примере, одним из предикатов был &amp;quot;c&amp;nbsp;3&amp;quot;. Поскольку этот предикат - неравенство, INDEX SEEK возвращает строки в порядке (c, a). И так как строки не отсортированы по столбцу &amp;quot;a&amp;quot;, мы не сможем использовать MERGE UNION.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Объединение трех индексов&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Оператор CONCATENATION может поддерживать больше двух входных потоков:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; a = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; c &amp;lt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Sort(DISTINCT ORDER BY:([Т]. [ а ]ASC))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Concatenation&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Clustered Index Seek(OBJECT:([Т].[Тa]), SEEK:([Т]. [ a ]=(1)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([ Т ].[ Тb ]), SEEK:([ Т ]. [ b ]=(2)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([Т].[Тc]), SEEK:([Т].[с] &amp;lt; (3)) ORDERED FORWARD)&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p align="justify"&gt;MERGE UNION поддерживает только два входных потока, но входные потоки можно объединять каскадом, чтобы позволяет в итоге объединить больше двух входных потоков:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; a = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; c = &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Stream Aggregate(GROUP BY:([Т]. [ a ]))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Merge Join(Concatenation)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Merge Join(Concatenation)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp; |--Clustered Index Seek(OBJECT:([Т].[Тa]), SEEK:([Т]. [ a ]=(1)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([ Т ].[ Тb ]), SEEK:([ Т ]. [ b ]=(2)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([Т].[Тc]), SEEK:([Т]. [ c ]=(3)) ORDERED FORWARD)&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Какие столбцы возвращает объединение?&lt;/p&gt;
&lt;p align="justify"&gt;Объединение возвращает только те столбцы, которые являются общими для всех его входных потоков. Во всех приведенных выше примерах индексных объединений, единственным столбцом, который у индексов был общим, являлся ключ кластеризованного индекса - колонка &amp;quot;a&amp;quot; (это как если бы индекс Tb состоял из столбцов &amp;quot;b, a&amp;quot;, а индекс Tc состоял из &amp;quot;c, a&amp;quot;). Таким образом, наше объединение может вернуть только столбец &amp;quot;a&amp;quot;. Если будут запрошены и другие столбцы, будет использоваться BOOKMARK LOOKUP. Так будет даже в том случае, если один из индексов в объединении будет покрывающим ещё для каких-либо столбцов. Например, если мы запросим все три столбца &amp;quot;a&amp;quot;, &amp;quot;b&amp;quot; и &amp;quot;c&amp;quot;, в плане исполнения будет BOOKMARK LOOKUP, несмотря на то, что столбец &amp;quot;b&amp;quot; будет покрываться индексом Тb, а столбец &amp;quot;c&amp;quot; будет покрываться индексом Тc:&lt;/p&gt;
&lt;table bgcolor="#ffffff" width="65%" cellpadding="2" cellspacing="10" border="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; a, b, c &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; T &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; b = &lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;or&lt;/span&gt; c = &lt;span style="color:#00008b;"&gt;&lt;b&gt;3&lt;/b&gt;&lt;/span&gt; &lt;/tt&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;tt&gt;&lt;small&gt;&amp;nbsp; |--Nested Loops(Inner Join, OUTER REFERENCES:([Т]. [ a ]))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Stream Aggregate(GROUP BY:([Т]. [ a ]))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp; |--Merge Join(Concatenation)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([ Т ].[ Тb ]), SEEK:([T]. [ b ]=(1)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Index Seek(OBJECT:([Т].[Тc]), SEEK:([Т]. [ c ]=(3)) ORDERED FORWARD)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |--Clustered Index Seek(OBJECT:([Т].[Тa]), SEEK:([Т]. [ a ]=[Т]. [ a ]) LOOKUP ORDERED FORWARD)&lt;/small&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/div&gt;</description></item><item><title>SQL Server Downgrade rights</title><link>http://msmvps.com/blogs/jeffloucks/archive/2009/10/02/sql-server-downgrade-rights.aspx</link><pubDate>Fri, 02 Oct 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1728922</guid><dc:creator>jeffl</dc:creator><description>&lt;p&gt;Every now and then you try to dig up the information regarding downgrade rights that come with your software. This post shows paths to downgrade SQL Server. Source: SQL Server Licensing Guide.&lt;br /&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sbs/0508.SQLDownGrade-Rights.PNG"&gt;&lt;img src="http://msmvps.com/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/sbs/0508.SQLDownGrade-Rights.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class="style1"&gt;Jeff &lt;/span&gt;&lt;span class="style2"&gt;Loucks&lt;br /&gt;&lt;/span&gt;&lt;span class="style2"&gt;Available Technology&lt;/span&gt;&lt;br /&gt;&lt;a target="_blank" href="http://www.availabletech.net" title="Available Technology"&gt;&lt;img height="70" width="250" src="http://www.availabletech.net/images/AvailableTechnologylogo2009.png" alt="Available Technology" /&gt;&lt;/a&gt;&lt;a href="http://msmvps.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/sbs/1588.SQLDownGrade-Rights.PNG"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Как справиться с PAGELATCH при больших INSERT-нагрузках</title><link>http://msmvps.com/blogs/gladchenko/archive/2009/09/28/1727878.aspx</link><pubDate>Mon, 28 Sep 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1727878</guid><dc:creator>gladchenko</dc:creator><description>&lt;div align="justify"&gt;
&lt;p align="justify"&gt;По материалам статьи: &amp;quot;&lt;a href="http://sqlcat.com/technicalnotes/archive/2009/09/22/resolving-pagelatch-contention-on-highly-concurrent-insert-workloads-part-1.aspx"&gt;Resolving PAGELATCH Contention on Highly Concurrent INSERT Workloads&lt;/a&gt;&amp;quot;.&lt;br /&gt;Авторы: Thomas Kejser, Lindsey Allen, Arvind Rao и Michael Thomassy&lt;br /&gt;При участии и с рецензиями: Mike Ruthruff, Lubor Kollar, Prem Mehra, Burzin Patel, Michael Thomassy, Mark Souza, Sanjay Mishra, Peter Scharlock, Stuart Ozer, Kun Cheng и Howard Yin&lt;br /&gt;Перевод &lt;a href="http://msmvps.com/blogs/gladchenko/default.aspx"&gt;Александра Гладченко&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Введение&lt;/b&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Недавно, мы проводили лабораторные испытания в Microsoft Enterprise Engineering Center, при которых использовалась большая рабочая нагрузка, характерная для OLTP систем. Целью этой лабораторной работы было определить, что случится при увеличении числа процессоров с 64 до 128, при обслуживании Microsoft SQL Server интенсивной рабочей нагрузки (примечание: эта конфигурация была ориентирована на релиз Microsoft SQL Server 2008 R2). Рабочая нагрузка представляла собой хорошо распараллеленные операции вставки, направляемые в несколько больших таблиц.&lt;br /&gt;Рабочая нагрузка масштабировалась до 128 процессорных ядер, но в статистике ожиданий было очень много кратких блокировок PAGELATCH_UP и PAGELATCH_EX. Средняя продолжительность ожидания была десятки миллисекунд, и таких ожиданий было очень много. Такое их количество оказалось для нас неожиданностью, ожидалось, что продолжительность не будет превышать несколько миллисекунд.&lt;br /&gt;В этой технической заметке вначале будет описано, как диагностировать подобную проблему и как для разрешения подобной проблемы использовать секционирование таблиц.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Диагностика проблемы&lt;/b&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Когда в &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms179984.aspx"&gt;sys.dm_os_wait_stats&lt;/a&gt; наблюдается большое число PAGELATCH, с помощью &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms188743.aspx"&gt;sys.dm_os_waiting_tasks&lt;/a&gt; можно определить сессию и ресурс, который задача ожидает, например, с помощью этого сценария:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; session_id, wait_type, resource_description&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.dm_os_waiting_tasks&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; wait_type &lt;span style="color:#777777;"&gt;LIKE&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;PAGELATCH%&amp;#39;&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;Пример результата:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://msmvps.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/gladchenko.agladchenko/6378.Output.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p align="justify"&gt;В столбце resource_description указаны местоположения страниц, к которым ожидают доступ сессии, местоположение представлено в таком формате:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&amp;lt;database_id&amp;gt;:&amp;lt;file_id&amp;gt;:&amp;lt;page_id&amp;gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Опираясь на значения в столбце resource_description, можно составить довольно сложный сценарий, который предоставит выборку всех попавших в список ожидания страниц:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; wt.session_id, wt.wait_type, wt.wait_duration_ms&lt;br /&gt;, s.name &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; schema_name&lt;br /&gt;, o.name &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#ff00ff;"&gt;object_name&lt;/span&gt;&lt;br /&gt;, i.name &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; index_name&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.dm_os_buffer_descriptors bd&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#777777;"&gt;JOIN&lt;/span&gt; (&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; *&lt;br /&gt;&amp;nbsp;&amp;nbsp;, &lt;span style="color:#ff00ff;"&gt;CHARINDEX&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;, resource_description) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; file_index&lt;br /&gt;&amp;nbsp;&amp;nbsp;, &lt;span style="color:#ff00ff;"&gt;CHARINDEX&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;, resource_description&lt;br /&gt;&amp;nbsp;&amp;nbsp;, &lt;span style="color:#ff00ff;"&gt;CHARINDEX&lt;/span&gt;(&lt;span style="color:#ff0000;"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;, resource_description)) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; page_index&lt;br /&gt;&amp;nbsp;&amp;nbsp;, resource_description &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; rd&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.dm_os_waiting_tasks wt&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; wait_type &lt;span style="color:#777777;"&gt;LIKE&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&amp;#39;PAGELATCH%&amp;#39;&lt;/span&gt;&lt;br /&gt;) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; wt&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; bd.database_id = &lt;span style="color:#ff00ff;"&gt;SUBSTRING&lt;/span&gt;(wt.rd, &lt;span style="color:#00008b;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;, wt.file_index)&lt;br /&gt;&lt;span style="color:#777777;"&gt;AND&lt;/span&gt; bd.&lt;span style="color:#ff00ff;"&gt;file_id&lt;/span&gt; = &lt;span style="color:#ff00ff;"&gt;SUBSTRING&lt;/span&gt;(wt.rd, wt.file_index, wt.page_index)&lt;br /&gt;&lt;span style="color:#777777;"&gt;AND&lt;/span&gt; bd.page_id = &lt;span style="color:#ff00ff;"&gt;SUBSTRING&lt;/span&gt;(wt.rd, wt.page_index, &lt;span style="color:#ff00ff;"&gt;LEN&lt;/span&gt;(wt.rd))&lt;br /&gt;&lt;span style="color:#777777;"&gt;JOIN&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.allocation_units&lt;/span&gt; au &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; bd.allocation_unit_id = au.allocation_unit_id&lt;br /&gt;&lt;span style="color:#777777;"&gt;JOIN&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.partitions&lt;/span&gt; p &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; au.container_id = p.partition_id&lt;br /&gt;&lt;span style="color:#777777;"&gt;JOIN&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.indexes&lt;/span&gt; i &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; p.index_id = i.index_id &lt;span style="color:#777777;"&gt;AND&lt;/span&gt; p.&lt;span style="color:#ff00ff;"&gt;object_id&lt;/span&gt; = i.&lt;span style="color:#ff00ff;"&gt;object_id&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#777777;"&gt;JOIN&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.objects&lt;/span&gt; o &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; i.&lt;span style="color:#ff00ff;"&gt;object_id&lt;/span&gt; = o.&lt;span style="color:#ff00ff;"&gt;object_id&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#777777;"&gt;JOIN&lt;/span&gt; &lt;span style="color:#008000;"&gt;sys.schemas&lt;/span&gt; s &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; o.schema_id = s.schema_id


&lt;pre&gt;&lt;/pre&gt;
&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Сценарий показал, что ожидаемые страницы относятся к кластеризованному индексу, определённому первичным ключом таблицы с представленной ниже структурой:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; HeavyInsert (&lt;br /&gt;ID &lt;span style="color:#0000ff;"&gt;INT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;PRIMARY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;KEY&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CLUSTERED&lt;/span&gt;&lt;br /&gt;, col1 &lt;span style="color:#0000ff;"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;) &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; [PRIMARY]&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Что происходит, почему возникает очередь ожиданий к страницам данных индекса - всё это будет рассмотрено в этой технической заметке.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Основная информация&lt;/b&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Чтобы определить, что происходит с нашей большой OLTP-нагрузкой, важно понимать, как SQL Server выполняет вставку в индекс новой строки. При необходимости вставки в индекс новой строки, SQL Server будет следовать следующему алгоритму внесения изменений:&lt;/p&gt;
&lt;ol&gt;
&lt;p&gt;
&lt;li&gt;В журнале транзакций создаётся запись о том, что строка изменилась.&lt;/li&gt;
&lt;li&gt;Осуществляется поиск в В-дереве местонахождения той страницы, куда должна будет попасть новая запись.&lt;/li&gt;
&lt;li&gt;Осуществляется наложение на эту страницу краткой блокировки PAGELATCH_EX, которая призвана воспрепятствовать изменениям из других потоков.&lt;/li&gt;
&lt;li&gt;Осуществляется добавление строки на страницу и, если это необходимо, осуществляется пометка этой страницы как &amp;quot;грязной&amp;quot;.&lt;/li&gt;
&lt;li&gt;Осуществляется снятие краткой блокировки со страницы.&lt;/li&gt;
&lt;/p&gt;
&lt;/ol&gt;
&lt;p align="justify"&gt;В итоге, страница должна будет быть сброшена на диск процессом контрольной точкой или отложенной записи.&lt;br /&gt;Если же все вставки строк направлены на ту же самую страницу, можно наблюдать рост очереди к этой странице. Даже притом, что краткая блокировка весьма непродолжительна, она может стать причиной конкуренции при высоком параллелизме рабочей нагрузки. У нашего клиента, первый и единственный столбец в индексе являлся монотонно возрастающим ключом. Из-за этого, каждая новая вставка шла на ту же самую страницу в конце В-дерева, пока эта страница не была заполнена. Рабочие нагрузки, которые используют в качестве первичного ключа IDENTITY или другие столбцы с последовательно увеличивающимися значениями, также могут столкнуться с подобной проблемой, если распараллеливание достаточно высоко.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Решение&lt;/b&gt;&lt;/p&gt;
&lt;p align="justify"&gt;Всегда, когда несколько потоков получают синхронный доступ к одному и тому же ресурсу, может проявиться описанная выше проблема. Стандартное решение состоит в том, чтобы создать больше ресурсов конкурентного доступа. В нашем случае, таким конкурентным ресурсом является последняя страница В-дерева.&lt;br /&gt;Одним из способов снизить конкуренцию за одну страницу состоит в том, чтобы выбрать в качестве первого столбца индекса другой, не увеличивающийся монотонно столбец. Однако, для нашего клиента это потребовало бы внесения изменений на прикладном уровне в клиентских системах. Мы должны были найти другое решение, которое могло бы ограничиться только изменениями в базе данных.&lt;br /&gt;Помните, что местом конкуренции является одна страница в В-дерева, и конкуренция была бы меньше, если бы было возможно использовать для этого несколько В-деревьев, и в то же время работать только с одной таблицей. К счастью, такая возможность есть, это: &lt;a href="http://msdn.microsoft.com/ru-ru/library/ms188706.aspx"&gt;Секционированные таблицы и индексы&lt;/a&gt;. Таблица может быть секционирована таким способом, чтобы новые строки размещались в нескольких секциях.&lt;br /&gt;Сначала нужно создать функцию и схему секционирования:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;CREATE PARTITION&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FUNCTION&lt;/span&gt; pf_hash (&lt;span style="color:#0000ff;"&gt;INT&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; RANGE &lt;span style="color:#777777;"&gt;LEFT&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;FOR&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;VALUES&lt;/span&gt; (&lt;span style="color:#00008b;"&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt;,&lt;span style="color:#00008b;"&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;,&lt;span style="color:#00008b;"&gt;&lt;b&gt;2&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;CREATE PARTITION SCHEME&lt;/span&gt; ps_hash &lt;span style="color:#0000ff;"&gt;AS PARTITION&lt;/span&gt; pf_hash &lt;span style="color:#777777;"&gt;ALL&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TO&lt;/span&gt; ([PRIMARY])&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Представленный выше пример использует четыре секции. Число необходимых секций зависит от числа активных процессов, выполняющих операции INSERT в описанную выше таблицу. Есть некоторая сложность в секционировании таблицы с помощью хэш-столбца, например, в том что всякий раз, когда происходит выборка строк из таблицы, будут затронуты все секции. Это означает, что придётся обращаться более чем к одному В-дереву, т.е. не будет отброшенных оптимизатором за ненадобностью ненужных секций. Будет дополнительная нагрузка на процессоры и некоторое увеличение времени ожиданий процессоров, что побуждает минимизировать число планируемых секций (их должно быть минимальное количество, при котором не наблюдается PAGELATCH). В рассматриваемом нами случае, в системе нашего клиента имелось достаточно много резерва в утилизации процессоров, так что было вполне возможно допустить небольшую потерю времени для инструкций SELECT, и при этом увеличить до необходимых объёмов норму инструкций INSERT.&lt;br /&gt;Ещё одной сложностью является то, что нужен дополнительный столбец, по которому будет выполняться секционирование, т.е. на основании значения которого будут распределяться вставки по четырем секциям. Такого столбца изначально в сценарии Microsoft Enterprise Engineering Center не было. Однако, его достаточно просто было создать. Для этого использовался тот факта, что столбец ID монотонно увеличивается с приращением равным единице, и здесь легко применима довольно простая хеш-функция:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;TABLE&lt;/span&gt; HeavyInsert_Hash(&lt;br /&gt;&amp;nbsp; ID &lt;span style="color:#0000ff;"&gt;INT&lt;/span&gt; &lt;span style="color:#777777;"&gt;NOT&lt;/span&gt; &lt;span style="color:#777777;"&gt;NULL&lt;/span&gt;&lt;br /&gt;&amp;nbsp; , col1 &lt;span style="color:#0000ff;"&gt;VARCHAR&lt;/span&gt;(&lt;span style="color:#00008b;"&gt;&lt;b&gt;50&lt;/b&gt;&lt;/span&gt;)&lt;br /&gt;&amp;nbsp; , HashID &lt;span style="color:#0000ff;"&gt;AS&lt;/span&gt; &lt;span style="color:#ff00ff;"&gt;CAST&lt;/span&gt;(&lt;span style="color:#ff00ff;"&gt;ABS&lt;/span&gt;(ID &lt;span style="color:#777777;"&gt;%&lt;/span&gt; &lt;span style="color:#00008b;"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;AS TINYINT&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;PERSISTED&lt;/span&gt; &lt;span style="color:#777777;"&gt;NOT NULL&lt;/span&gt;)&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;С помощью столбца HashID, вставки в четыре секции будут выполняться циклически.&lt;br /&gt;Создаём кластеризованный индекс следующим образом:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;CREATE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;UNIQUE&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;CLUSTERED&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;INDEX&lt;/span&gt; CIX_Hash&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; HeavyInsert_Hash (ID, HashID) &lt;span style="color:#0000ff;"&gt;ON&lt;/span&gt; ps_hash(HashID)&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Используя новую схему таблицы с секционированием вместо первоначального варианта таблицы, мы сумели избавиться от очередей PAGELATCH и повысить скорость вставки. Этого удалось достичь за счёт балансировки вставки между несколькими секциями и высокого параллелизма. Вставка происходит в несколько страниц, и каждая страница размещается в своей собственной структуре В-дерева. Для нашего клиента удалось повысить производительность вставки на 15 процентов, и справится с большой очередью PAGELATCH к горячей странице индекса одной таблицы. Но при этом удалось также оставить достаточно большой резерв циклов процессоров, что оставило возможность сделать аналогичную оптимизацию для другой таблицы, тоже с высокой нормой вставки.&lt;br /&gt;Строго говоря, суть этой уловки в оптимизации логической схемы первичного ключа таблицы. Однако, потому что ключ просто стал длиннее на величину хеш-функции относительно изначального ключа, дубликатов для столбца ID удалось избежать. Уникальные индексы по единственному столбцу таблицы зачастую становятся причиной проблем с очередями PAGELATCH. Но даже если эту проблему удастся устранить, у таблицы может оказаться другой, некластеризованный индекс, который будет подвержен той же самой проблеме. Как правило, проблема наблюдается для уникальных ключей на единственном столбце, где каждая вставка попадает на одну и ту же страницу. Если и у других таблиц индексы подвержены проблеме с PAGELATCH, можно применить эту же уловку с секционированием к индексам таких таблиц, используя такой же ключ с хэшем в качестве первичного ключа.&lt;br /&gt;Не всегда возможно внести изменения в приложение, особенно, если оно является плодом усилий третьих фирм. Но если изменение запросов возможно, становится доступной их оптимизация за счёт добавления к ним условий фильтрации по предикатам первичного ключа.&lt;/p&gt;
&lt;p align="justify"&gt;Пример: Чтобы отбросить ненужные секции, можно внести следующие изменения в сценарий:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; HeavyInsert_Hash&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; ID = &lt;span style="color:#00008b;"&gt;&lt;b&gt;42&lt;/b&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;Который после изменений будет выглядеть так:&lt;/p&gt;
&lt;ul&gt;
&lt;p&gt;&lt;tt&gt;&lt;span style="color:#0000ff;"&gt;SELECT&lt;/span&gt; * &lt;span style="color:#0000ff;"&gt;FROM&lt;/span&gt; HeavyInsert_Hash&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;WHERE&lt;/span&gt; ID = &lt;span style="color:#00008b;"&gt;&lt;b&gt;42&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#777777;"&gt;AND&lt;/span&gt; HashID = &lt;span style="color:#00008b;"&gt;&lt;b&gt;42&lt;/b&gt;&lt;/span&gt; % &lt;span style="color:#00008b;"&gt;&lt;b&gt;4&lt;/b&gt;&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p align="justify"&gt;Исключение оптимизатором ненужных секций по значению хэша не будет вам ничего стоить, если только не считать большой платой за это увеличение на один байт каждой строки кластеризованного индекса. &lt;/p&gt;
&lt;/div&gt;</description></item><item><title>How do I monitor problems with replication?</title><link>/http://sqlserver-qa.net/blogs/replication/archive/2009/09/24/6000.aspx</link><pubDate>Thu, 24 Sep 2009 05:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1726342</guid><dc:creator>Anonymous</dc:creator><description>When you setup a program or application then you have equal responsibility to monitor the process/problems too. Similar to this monitoring a replication topology is an important aspect of deploying SQL Server replication. As the process is distributed and it is essential to track activity and status across all computers involved in replication. We have bunch of tools that can help the user/DBA/Developer to monitor replication, they are: Replication Monitor: most important tool for monitoring replication,...(&lt;a href="http://sqlserver-qa.net/blogs/replication/archive/2009/09/24/6000.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://sqlserver-qa.net/aggbug.aspx?PostID=6000" width="1" height="1" alt="" /&gt;</description></item></channel></rss>