<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BI Monkey &#187; SQL Server</title>
	<atom:link href="http://www.bimonkey.com/tag/sql-server/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bimonkey.com</link>
	<description>James Beresford on Microsoft BI and Consulting in Sydney, Australia</description>
	<lastBuildDate>Mon, 23 Jan 2012 22:01:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>SQL Pass Day #1</title>
		<link>http://www.bimonkey.com/2011/10/sql-pass-day-1/</link>
		<comments>http://www.bimonkey.com/2011/10/sql-pass-day-1/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 00:28:36 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[Microsoft BI]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Data Quality Services]]></category>
		<category><![CDATA[Denali]]></category>
		<category><![CDATA[Integration Services]]></category>
		<category><![CDATA[SQL Pass 2011]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=1091</guid>
		<description><![CDATA[So the BI Monkey was at PASS and intended blogging on his phone or at one of the many internet pods provided, but sadly WordPress and IE / Android aren&#8217;t friends so this is going to be a retrospective. So, here are my takeaways from day 1: From the keynote: Denali becomes SQL2012 and is [...]]]></description>
			<content:encoded><![CDATA[<p>So the BI Monkey was at PASS and intended blogging on his phone or at one of the many internet pods provided, but sadly WordPress and IE / Android aren&#8217;t friends so this is going to be a retrospective.</p>
<p>So, here are my takeaways from day 1:</p>
<p><em>From the keynote:</em></p>
<p>Denali becomes SQL2012 and is slated for release in the first half of next year (way to allow yourself some leeway on the final release date!)</p>
<p>Crescent becomes Power View &#8211; and will work on multiple mobile platforms &#8211; Apple &amp; Android via Browser, WP7 via a richer app</p>
<p>HADOOP is going to be supported in Windows server &#8211; the first CTP is due next year. If you have access to the PASS DVD&#8217;s / Sessions &#8211; see Dr Dewitt&#8217;s presentation on HADOOP &#8211; very enlightening</p>
<p><em>From wandering around the summit:</em></p>
<p>As per Elad Ziklik of the DQS team, performance is one of their focuses for the next release</p>
<p>I got to finally meet Ivan Peev of <a title="CozyRoc" href="http://www.cozyroc.com/">CozyRoc</a> after many years of email and phone conversations, and he told me about their new SAS Connector &#8211; which allows reading and writing to SAS datasets without an actual SAS install.</p>
<p>I also got to meet Matt Masson, guru of the SSIS team who told me about <a title="Project Barcelona Team Blog" href="http://blogs.msdn.com/b/project_barcelona_team_blog/">Project Barcelona</a> &#8211; a tool that will do data lineage, metadata management and impact analysis via a crawler as opposed to a manually maintained set.</p>
<p>I also got to sit in on a customer feedback session about BI in the Cloud &#8211; unfortunately all under NDA &#8211; but it was a great forum to discuss and help direct Microsoft&#8217;s Cloud BI ambitions.</p>
<p>I also had a chat with fellow Aussie BI guy <a title="Roger Noble" href="http://www.rogernoble.com/">Roger Noble</a> who told me about a use for the Term Extraction transformation in SSIS &#8211; using it to scan through documents and auto-tag them as the were uploaded to SharePoint &#8211; which is pretty cool.</p>
<p>So, that was Day 1&#8230; Day 2 to follow!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2011/10/sql-pass-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Columnstore Indexes revisited</title>
		<link>http://www.bimonkey.com/2011/09/columnstore-indexes-revisited/</link>
		<comments>http://www.bimonkey.com/2011/09/columnstore-indexes-revisited/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 23:27:22 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Columnstore]]></category>
		<category><![CDATA[Denali]]></category>
		<category><![CDATA[Indexes]]></category>
		<category><![CDATA[Vertipaq]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=1058</guid>
		<description><![CDATA[Having now researched Columnstore Indexes further, I thought I&#8217;d share the key learning I&#8217;ve picked up on this feature &#8211; which now sounds even more powerful than I&#8217;d originally thought. The most important thing to take away is that a Columnstore Index should actually cover the entire table. Its name is a little misleading &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Having now researched Columnstore Indexes further, I thought I&#8217;d share the key learning I&#8217;ve picked up on this feature &#8211; which now sounds even more powerful than I&#8217;d originally thought.</p>
<p>The most important thing to take away is that a Columnstore Index should actually cover the <strong>entire table</strong>. Its name is a little misleading &#8211; the feature is less of an index, and more of a shadow copy of the table&#8217;s data, compressed with the Vertipaq voodoo. I suspect they have used the term index because the Columnstore doesn&#8217;t cover all data types &#8211; the important ones are there, but some extreme decimals and blobs are excluded &#8211; for a full list see the <a title="Columnstore Indexes MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/gg492088%28v=sql.110%29.aspx">MSDN documentation</a>. So for any big table, whack a Columnstore index across the entire table.</p>
<p>Next up is to understand how to use them and how to detect when they are or are not being used. The key thing is to only use them in isolation (e.g. summary queries) or for <strong>Inner Joins</strong>. Outer Joins don&#8217;t work right now, though there are cunning workarounds that apply if you are Outer Joining to summary data &#8211; see Eric Hanson&#8217;s video referenced below somewhere around the 50 minute mark.</p>
<p>You can detect when they are being used by the Execution Mode described in the Query Plan. This is new in Denali and is either Row or Batch. Row means traditional SQL Server execution and Batch means the Columnstore is being used.</p>
<p>So, the key takeaways:</p>
<ul>
<li>For any large table put a Columnstore index across the entire table</li>
<li>Only join using Inner Joins</li>
<li>Spot the use of the Columnstore in Query plans via the Execution Mode of Batch</li>
</ul>
<p>Useful reference material:</p>
<ul>
<li><a title="Columnstore Indexes Unveiled" href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DBI312">Eric Hanson&#8217;s Tech-Ed video</a> (a bit dull, but informative &#8211; if you know your Data Warehousing theory, skip the first 15 minutes)</li>
<li>The TechNet <a title="    Article     History  SQL Server Columnstore Index FAQ" href="http://social.technet.microsoft.com/wiki/contents/articles/sql-server-columnstore-index-faq.aspx">Columnstore Index FAQ</a></li>
<li><a title="Columnstore Indexes for Fast Data Warehouse Query Processing in SQL Server 11.0" href="http://download.microsoft.com/download/8/C/1/8C1CE06B-DE2F-40D1-9C5C-3EE521C25CE9/Columnstore%20Indexes%20for%20Fast%20DW%20QP%20SQL%20Server%2011.pdf">Columnstore Indexes for Fast Data Warehouse Query Processing in SQL Server 11.0</a> &#8211; Whitepaper by Eric Hanson</li>
<li><a title="Columnstore Indexes MSDN Documentation" href="http://msdn.microsoft.com/en-us/library/gg492088%28v=sql.110%29.aspx">MSDN documentation</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2011/09/columnstore-indexes-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OLE DB is dead &#8211; Long live ODBC!</title>
		<link>http://www.bimonkey.com/2011/09/ole-db-is-dead-long-live-odbc/</link>
		<comments>http://www.bimonkey.com/2011/09/ole-db-is-dead-long-live-odbc/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 04:21:53 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[Integration Services]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[ODBC]]></category>
		<category><![CDATA[OLE DB]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=1055</guid>
		<description><![CDATA[Something I picked up in passing at the MSDN SSIS forum &#8211; SQL Native Client OLE DB is being deprecated post Denali. See this post on the SQL Native Client Team Blog. What does this mean? First up this only applies to SQL Server connections &#8211; other OLE DB connectivity such as Teradata and Oracle [...]]]></description>
			<content:encoded><![CDATA[<p>Something I picked up in passing at the <a title="SQL Server Integration Services" href="http://social.msdn.microsoft.com/Forums/en-US/sqlintegrationservices/threads">MSDN SSIS forum</a> &#8211; SQL Native Client OLE DB is being deprecated post Denali. See <a title="Microsoft is Aligning with ODBC for Native Relational Data Access" href="http://blogs.msdn.com/b/sqlnativeclient/archive/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access.aspx">this post on the SQL Native Client Team Blog</a>.</p>
<p>What does this mean?</p>
<ol>
<li>First up this only applies to SQL Server connections &#8211; other OLE DB connectivity such as Teradata and Oracle will be unaffected.</li>
<li>In the short term, nothing &#8211; if you are using OLE DB it will carry on working for a fair few years yet &#8211; but if you are planning for a systems longevity &#8211; look to using ODBC for all your SQL Server connectivity needs</li>
</ol>
<p>It&#8217;s a slightly confusing move given that ODBC underperforms OLE DB &#8211; so it&#8217;s bad news for us SSIS people, unless part of the change also includes some significant performance and capability improvements.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2011/09/ole-db-is-dead-long-live-odbc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Columnstore indexes in Denali (aka: &#8220;Apollo&#8221;)</title>
		<link>http://www.bimonkey.com/2011/08/columnstore-indexes-in-denali-aka-apollo/</link>
		<comments>http://www.bimonkey.com/2011/08/columnstore-indexes-in-denali-aka-apollo/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 04:52:39 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Columnstore]]></category>
		<category><![CDATA[Denali]]></category>
		<category><![CDATA[Indexes]]></category>
		<category><![CDATA[Vertipaq]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=1010</guid>
		<description><![CDATA[James Serra has a great post on a new feature in SQL Server Denali &#8211; Columnstore indexes. The tl/dr version is this: Columnstore indexes use the Vertipaq compression engine (that&#8217;s the shiny compression engine in PowerPivot) to further compact indexes to make querying them between 10-100 times faster. The most significant limitation is that tables [...]]]></description>
			<content:encoded><![CDATA[<p><a title="James Serra" href="http://www.jamesserra.com/">James Serra</a> has a <a title="SQL Server “Denali”: Project Apollo" href="http://www.jamesserra.com/archive/2011/08/sql-server-%e2%80%9cdenali%e2%80%9d-project-apollo/">great post on a new feature in SQL Server Denali &#8211; Columnstore indexes</a>.</p>
<p>The tl/dr version is this:</p>
<p>Columnstore indexes use the Vertipaq compression engine (that&#8217;s the shiny compression engine in PowerPivot) to further compact indexes to make querying them between 10-100 times faster.</p>
<p>The most significant limitation is that tables become read-only when they have a columnstore index (no Inserts / Updates / Deletes etc) &#8211; though James notes you can work around this by using Partitions if you are dealing with tables that are just additive. Otherwise indexes will need to be dropped and recreated as data changes.</p>
<p>So &#8211; a powerful new indexing feature which, with careful management &#8211; can have a serious positive impact on the performance of your Data Warehouse.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2011/08/columnstore-indexes-in-denali-aka-apollo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BI Documenter from Pragmatic Works</title>
		<link>http://www.bimonkey.com/2010/08/bi-documenter-from-pragmatic-works/</link>
		<comments>http://www.bimonkey.com/2010/08/bi-documenter-from-pragmatic-works/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 10:44:11 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[Microsoft BI]]></category>
		<category><![CDATA[3rd Party Tools]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=796</guid>
		<description><![CDATA[I recently had to demo SSIS to an enterprise as part of an ETL tool evaluation. One of the Microsoft BI stacks weaknesses is the lack of Data Lineage tracking. What this means is there is nothing embedded in the toolset that allows you to identify clearly the source of a data item in a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to demo SSIS to an enterprise as part of an ETL tool evaluation. One of the Microsoft BI stacks weaknesses is the lack of Data Lineage tracking. What this means is there is nothing embedded in the toolset that allows you to identify clearly the source of a data item in a package / report / cube without digging into the development environment. Rumours are this will be fixed in the next release, however nothing has yet been confirmed.</p>
<p>However, where the Microsoft BI stack has a competitor beating edge is the 3rd Party ecosystem &#8211; so where there is a gap in the toolset, often another company will step in and fill it. In this case, Data Lineage issues are addressed by a tool created by <a title="Pragmatic Works" href="http://pragmaticworks.com/">Pragmatic Works</a> (which is run by Brian Knight, an SSIS heavyweight) called BI Documenter.</p>
<h2>BI Documenter Review</h2>
<p>So what does the tool do? It has 3 key functions:</p>
<p><strong>Documentation Generation:</strong> The tool auto-generates documentation for Databases, SSIS packages, SSAS Cubes and SSRS reports. It&#8217;s quick, and the output is pretty &#8211; and it&#8217;s really a bit useless. Its benefit is if you have to say you&#8217;ve produced some documentation and need to do so with minimal effort. The reason I say this is because it provides no context for why things have been done, what the purpose of the component is, where it fits in to the framework etc. My usual gripe with documentation I come across is that it only tells me the what, not the why, and the why helps me solve a problem. This tool can&#8217;t do anything to address this.</p>
<p><strong>Data Lineage:</strong> Now this is where the main value lies. Through simple navigation you can select any object (table / view / package etc) in the solution and see what objects depend on it and what objects it depends on in turn. This is great in a complex system where if you need to make a change and need to find out what that impacts.</p>
<p>Now its not perfect &#8211; it seems to skip documenting some sources, such as flat files, so they get missed in the impact analysis. And the level of granularity is at the object level &#8211; for example you can&#8217;t see the impact of an individual column change, just at the table level, but its still a great start and a useful tool.</p>
<p><strong>Snapshot comparison:</strong> A final piece of value which can be useful in troubleshooting. BI Documenter takes snapshots of your solution to document &#8211; and you can compare these to identify changes in the solution. The detail level is pretty good and will be a great place to start tracing changes in your system when your source control systems fail.</p>
<h2>Conclusions</h2>
<p>Is the tool worth it? At a maximum cost of US$500 a seat, it&#8217;s definitely got a place somewhere in your organisation. The documentation tool is of limited use but the Data Lineage and Snapshot comparisons are worth the cost of the product. Full details here: <a title="Pragmatic Works - BI Documenter" href="http://pragmaticworks.com/Products/Business-Intelligence/BIDocumenter/Default.aspx">Pragmatic Works &#8211; BI Documenter</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2010/08/bi-documenter-from-pragmatic-works/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Managing your history data</title>
		<link>http://www.bimonkey.com/2010/05/managing-your-history-data/</link>
		<comments>http://www.bimonkey.com/2010/05/managing-your-history-data/#comments</comments>
		<pubDate>Tue, 11 May 2010 00:11:38 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[Analysis Services]]></category>
		<category><![CDATA[Integration Services]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=762</guid>
		<description><![CDATA[This post is to an extent a small rant about some design decisions I have been constrained by on my current project. These decisions were made predominantly for one fairly bad reason: it made the architect&#8217;s life easier (apologies to the architects if they are reading &#8211; but these were bad choices!) The design choices in [...]]]></description>
			<content:encoded><![CDATA[<p>This post is to an extent a small rant about some design decisions I have been constrained by on my current project. These decisions were made predominantly for one fairly bad reason: it made the architect&#8217;s life easier (apologies to the architects if they are reading &#8211; but these were bad choices!)</p>
<p>The design choices in question are around the managing of history data. In one component of the system it relates to Database storage design, the other relates to Cube storage design. In both cases the history data is stored in a separate location to the &#8220;current&#8221; data.</p>
<h2>Databases: Why separate history tables are a bad idea</h2>
<p>The first &#8211; and most compelling &#8211; reason for not storing your history data in separate tables to your current tables is that it increases complexity for users. Instead of having one location to look for data, your users now have to use two.</p>
<p>The second compelling reason is that there is no point to doing this from a storage point of view. SQL 2005 &amp; 2008 (<span style="text-decoration: underline;">Enterprise</span> editions only, admittedly) provide <a title="Partitioned Tables and Indexes in SQL Server 2005" href="http://msdn.microsoft.com/en-us/library/ms345146(SQL.90).aspx">partitioning</a>. This enables the contents of an individual table to be stored in separate locations on different <a title="Using Files and Filegroups" href="http://msdn.microsoft.com/en-us/library/ms187087.aspx">filegroups</a>. This means that you can store your current days data in one location and your history in a different one. The reason for doing this is the same as splitting it into separate tables &#8211; that querying the current section will be faster than the historic section.  In theory queries against partitioned tables should in fact be faster as the current data is now no longer in the same filegroup as the history data.</p>
<p>Now, there is an overhead associated with designing and maintaining partitions but I don&#8217;t see that it is significantly larger than that required to deal with the process required to archive data into separate tables on a daily basis. Additionally when maintaining separate history tables, you need to separate out every single table, whether it gets 10 rows a day or 10 million. With partitioning you can just target the large tables that need that focus.</p>
<p>There are other downsides to maintaining separate tables. If you make a change to a table design, you need to do it in 2 places.  You also need to remember to update your history processes. If your history process fails, you can end up with users getting unexpected query results or ETL process failures when the system loads the next day&#8217;s data into the current tables &#8211;  and untangling it becomes a real mess. If your partition processes fail to run, you just have too much data in one filegroup for a while &#8211; unlikely to be fatal.</p>
<p>So if you have large tables you need to split out for performance purposes &#8211; do it at the back end, using the power of the database &#8211; which <strong>is</strong> designed to store data efficiently. Keep it away from the users &#8211; they neither need to know or care about your need to keep the data separate. If you want to give them a single object to query with the current day&#8217;s data, just use views.</p>
<h2>Cubes: Why a separate history Cube is a bad idea</h2>
<p>Much of the above applies here &#8211; <a title="Managing Analysis Services Partitions" href="http://msdn.microsoft.com/en-us/library/ms175604.aspx">SSAS also has partitions</a> &#8211; so you can again store your historic and current data in separate physical locations with the users being totally unaware of this. Again there is overhead in maintenance, but this will also balance out with the maintenance and risks associated with maintaining two identical cubes that only differ in terms of data source.</p>
<h2>Use your storage options!</h2>
<p>So without banging on about the same things any further, please consider the following two points whenever considering managing your history data:</p>
<ol>
<li>How does what i&#8217;m planning affect my users?</li>
<li>How does what i&#8217;m planning leverage the platforms capabilities?</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2010/05/managing-your-history-data/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SQL Server Aliases</title>
		<link>http://www.bimonkey.com/2010/04/sql-server-aliases/</link>
		<comments>http://www.bimonkey.com/2010/04/sql-server-aliases/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 23:33:31 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=756</guid>
		<description><![CDATA[As part of a meeting on setting up DR systems, one of the Server Techs mentioned using SQL Server Aliases to allow the cubes to be identical in structure &#8211; right down to connections &#8211; yet live on separate environments and point at different SQL Servers. This was news to me, but a quick google [...]]]></description>
			<content:encoded><![CDATA[<p>As part of a meeting on setting up DR systems, one of the Server Techs mentioned using SQL Server Aliases to allow the cubes to be identical in structure &#8211; right down to connections &#8211; yet live on separate environments and point at different SQL Servers. This was news to me, but a quick google turned this up: <a title="How to setup and use a SQL Server alias" href="http://www.mssqltips.com/tip.asp?tip=1620">How to setup and use a SQL Server alias</a>.</p>
<p>An Alias is an Operating System level setting that allows you give a friendly name to your Server &#8211; and you can then connect to the server using that friendly name. What this means is that as you migrate your code from environment to environment, if you use the same friendly name for your SQL Server in each tier of the deployment, you don&#8217;t have to change your connection strings.</p>
<p>It&#8217;s a neat trick (though i&#8217;m not sure how the names resolve if you use the same name in environments that can see each other) &#8211; it certainly requires some proper planning from an infrastructure point of view.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2010/04/sql-server-aliases/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>AUSSUG Upcoming Sessions</title>
		<link>http://www.bimonkey.com/2010/02/aussug-upcoming-sessions/</link>
		<comments>http://www.bimonkey.com/2010/02/aussug-upcoming-sessions/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 10:54:45 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[BI Monkey News]]></category>
		<category><![CDATA[Microsoft BI]]></category>
		<category><![CDATA[Presentations]]></category>
		<category><![CDATA[Integration Services]]></category>
		<category><![CDATA[PerformancePoint]]></category>
		<category><![CDATA[Reporting Services]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=734</guid>
		<description><![CDATA[In case you aren&#8217;t in the Australian SQL Server User Group, AUSSUG, there are a few upcoming sessions in Sydney which will be pretty useful &#8211; check out the official site to register. Sessions are free and always useful. Lunchtime Wed 3rd March, 2010 &#8211; Ensuring Optimal Performance in SQL Server 2008 Based Applications with [...]]]></description>
			<content:encoded><![CDATA[<p>In case you aren&#8217;t in the Australian SQL Server User Group, <a title="Australian SQL Server User Group" href="http://www.sqlserver.org.au/">AUSSUG</a>, there are a few upcoming sessions in Sydney which will be pretty useful &#8211; check out the official site to register. Sessions are free and always useful.</p>
<p><strong>Lunchtime Wed 3rd March, 2010</strong> &#8211; Ensuring Optimal Performance in SQL Server 2008 Based Applications with Viktor Isakov</p>
<p><strong>Evening * Thu * 4th Mar 2010</strong> &#8211; What&#8217;s new in Reporting Services 2008 R2 and PerformancePoint Services 2010 with Peter Myers, presenting what&#8217;s new in the upcoming release of Reporting Services 2008 R2 and PerformancePoint Services 2010</p>
<p>And TBA date in <strong>April 2010</strong> &#8211; Knights of the SSIS Round Table &#8211; Kevin Wong, Glyn Llewelyn and <strong>myself </strong>will be presenting a series of mini demos followed by Q&amp;A, so a chance to pick some expert brains</p>
<p>Hope to catch you at one of the sessions!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2010/02/aussug-upcoming-sessions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server 2008 Auditing</title>
		<link>http://www.bimonkey.com/2009/12/sql-server-2008-auditing/</link>
		<comments>http://www.bimonkey.com/2009/12/sql-server-2008-auditing/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 11:52:08 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Audit]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=694</guid>
		<description><![CDATA[I recently got presented with this challenge: How do you monitor people disabling your SQL Agent Jobs? Not prevent, warn or notify&#8230; just be able to monitor and find out who did what, when? Enter SQL Server Auditing, introduced in 2008. What is SQL 2008 Auditing? Well, you could read the official documentation on MSDN, but [...]]]></description>
			<content:encoded><![CDATA[<p>I recently got presented with this challenge: How do you monitor people disabling your SQL Agent Jobs? Not prevent, warn or notify&#8230; just be able to monitor and find out who did what, when?</p>
<p>Enter <strong>SQL Server Auditing</strong>, introduced in 2008.</p>
<h2>What is SQL 2008 Auditing?</h2>
<p>Well, you could <a title="Understanding SQL Server Audit" href="http://msdn.microsoft.com/en-us/library/cc280386.aspx">read the official documentation on MSDN</a>, but it&#8217;s a little overwhelming, so here&#8217;s the view from 500 ft. SQL Server Audit provides a secure means of tracking access and changes made to the database schema or its data. What this means is you can trace who tried to access what and when. If any command was issued to change the data, you can track this as well. You <span style="text-decoration: underline;">cannot</span> track the changes made to the data. So for example if someone made an insert into a table, you could track that someone made an insert, who did it, when that insert was made and what the SQL of the insert statement looked like &#8211; except for what data was inserted. That task falls to Change Data capture (CDC) which isn&#8217;t directly tied to Auditing (currently).</p>
<h2>How do I implement Auditing?</h2>
<p>A SQL Server Audit is made up of two components, the first of which is the SQL Server Audit. This is a server level object (created in the <strong>master</strong> database) that defines where logs will be written. Logs can be written to either a file, the Application Log or Security Log. These must be created before you create any actual Audits.</p>
<p>The second component is either a Server Audit or Database Audit. Server Audits again exist at the server level, and track activities that occur at the server level, such as login attempts or permission changes. Database Audits exist within an individual database and track activities at a database level such as schema changes or data operations.</p>
<p>You can have multiple SQL Server Audits defining multiple log target locations. Multiple Server and Database audits can be created to use a given SQL Server Audit. This probably makes more sense when explained in pictures:</p>
<div class="wp-caption alignnone" style="width: 571px"><a href="http://www.bimonkey.com/uploads/sql/SQLAudit.jpg"><img class=" " title="SQL 2008 Auditing Hierarchy" src="http://www.bimonkey.com/uploads/sql/SQLAudit.jpg" alt="SQL 2008 Auditing Hierarchy" width="561" height="398" /></a><p class="wp-caption-text">Fig 1: SQL 2008 Auditing Hierarchy</p></div>
<p> </p>
<h2>So how do I audit my SQL Agent Jobs?</h2>
<p>Setting up Audits can either be done through SQL Server Management Studio (SSMS) or through SQL scripts. As usual any action carried out through the Wizard, so I will do the wizard first, then show the generated scripts.</p>
<p>Step 1 is setting up the SQL Server Audit. To create this in SSMS, under the Security Node of the Server is a folder called &#8220;Audits&#8221;. To create a new Audit, simply right click on the folder and choose &#8220;New Audit..&#8221;, as set out below:</p>
<div class="wp-caption alignnone" style="width: 382px"><img class="   " title="Creating a SQL Server Audit" src="http://www.bimonkey.com/uploads/sql/sqlserveraudit_ssms.jpg" alt="Creating a SQL Server Audit" width="372" height="409" /><p class="wp-caption-text">Fig 2: Creating a SQL Server Audit</p></div>
<p>Then in the Wizard just enter the Audit name and in the dropdown select &#8220;Application Log&#8221;, as shown below. The alternatives are to the Security Log or to a File, but I won&#8217;t be covering those in this simple example. Click on OK and you&#8217;re done.</p>
<div class="wp-caption alignnone" style="width: 691px"><img class="   " title="Creating a SQL Server Audit" src="http://www.bimonkey.com/uploads/sql/sqlserveraudit_ssms_new_audit.jpg" alt="Creating a SQL Server Audit" width="681" height="250" /><p class="wp-caption-text">Fig 3: Creating a SQL Server Audit</p></div>
<p>The equivalent SQL script is below:</p>
<blockquote><p><span style="color: #0000ff;">USE </span>[master]</p>
<p><span style="color: #0000ff;">GO</span></p>
<p><span style="color: #0000ff;">CREATE SERVER</span> AUDIT [My Sample Audit]<br />
<span style="color: #0000ff;">TO</span> APPLICATION_LOG<br />
<span style="color: #0000ff;">WITH</span><br />
( QUEUE_DELAY = 1000<br />
 ,ON_FAILURE = <span style="color: #0000ff;">CONTINUE</span><br />
)</p>
<p><span style="color: #0000ff;">GO</span></p></blockquote>
<p>Now you have somewhere to write your log. Note that by default SQL Server Audits are <strong>disabled</strong> when they are created, which means nothing will be written to your log until until it is enabled. This can be done just by right clicking on it in SSMS and choosing &#8220;Enable&#8221;.</p>
<p>The next bit is to set up the Database Audit on the SQL Agent Jobs table, which is in the system table [msdb].[dbo].[sysjobs]. Under the msdb database, open up the &#8220;Security&#8221; folder and within there is the &#8220;Database Audit Specifications&#8221; folder. Right click here and choose &#8220;New Database Audit Specification&#8230;&#8221; as shown below.</p>
<div class="wp-caption alignnone" style="width: 572px"><img class="    " title="Creating a Database Audit Specification" src="http://www.bimonkey.com/uploads/sql/databaseaudit_ssms.jpg" alt="Creating a Database Audit Specification" width="562" height="647" /><p class="wp-caption-text">Fig 4: Creating a Database Audit Specification</p></div>
<p>This will open the Create Database Audit Specification dialog. Because we are operating on msdb, unless you are logged in as <strong>sa</strong>, you probably won&#8217;t be able to create objects and the process will fail. So ensure the user you are logged in as has appropriate permissions on msdb. Because I&#8217;m playing on a Dev environment, I just allowed my own user access to msdb and gave them db_owner rights &#8211; this probably won&#8217;t fly in a production environment, of course!</p>
<p>The dialog is shown below. First task is to choose which SQL Server Audit to write to &#8211; so we use the one we created above called &#8221;My Sample Audit&#8221;. You choose the Audit Action Type &#8211; i.e. what you want to log. In our case we want to see when changes are made to our jobs in SQL Agent, so we choose the &#8220;UPDATE&#8221; Action Type. Next we have the Object Class, which for this case is a Database Object, so &#8220;Object&#8221; is selected, and then the Object Name. Finally the Principal defines who is Audited &#8211; in the example I have selected &#8220;public&#8221; because every user is in the public role, so I will capture any users UPDATE commands issued on my selected table.</p>
<div class="wp-caption alignnone" style="width: 1052px"><img class="   " title="Creating a Database Audit Specification" src="http://www.bimonkey.com/uploads/sql/sqlserveraudit_ssms_new_dbaudit.jpg" alt="Creating a Database Audit Specification" width="1042" height="288" /><p class="wp-caption-text">Fig 5: Creating a Database Audit Specification</p></div>
<p>Now here we hit a minor hiccup &#8211; you will note in the example above I have selected the object sysdtslog90 &#8211; it&#8217;s the only non-system view in the database, and the only one I can get to come up in the browser. The solution here is just to hit the &#8220;Script&#8221; button, and modify the generated code to point at the right table, as shown below:</p>
<blockquote><p><span style="color: #0000ff;">USE</span>[msdb]</p>
<p><span style="color: #0000ff;">GO</span></p>
<p><span style="color: #0000ff;">CREATE DATABASE</span> AUDIT SPECIFICATION [SQL Agent Audit]<br />
<span style="color: #0000ff;">FOR SERVER</span> AUDIT [My Sample Audit]<br />
<span style="color: #0000ff;">ADD</span> (<span style="color: #0000ff;">UPDATE ON OBJECT</span>::<strong>[dbo].[sysjobs]</strong> <span style="color: #0000ff;">BY</span> [public])</p>
<p>GO</p></blockquote>
<p>This code runs just fine, and as you will see has the desired effect. As with SQL Server Audits, Database Audit Specifications are created in a disabled state. As before, just right click to enable and the Auditing will begin.</p>
<p>Finally to test, just change the Enabled state of any SQL Agent job on your server, then check the Application Log, where you will find an Event detailing who just changed its status!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2009/12/sql-server-2008-auditing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Count the number of rows in every Table in a Database in no time!</title>
		<link>http://www.bimonkey.com/2009/06/count-the-number-of-rows-in-every-table-in-a-database-in-no-time/</link>
		<comments>http://www.bimonkey.com/2009/06/count-the-number-of-rows-in-every-table-in-a-database-in-no-time/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 04:47:43 +0000</pubDate>
		<dc:creator>BI Monkey</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[DMV]]></category>
		<category><![CDATA[Row Count]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://www.bimonkey.com/?p=307</guid>
		<description><![CDATA[Here is a piece of T-SQL code that uses DMV&#8217;s (Dynamic Management Views) to give an approximate row count of every table in your database in virtually no time at all. Bear in mind it is running off collected statistics so won&#8217;t always be 100% accurate &#8211; but it&#8217;s far quicker than doing a Count(*) [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a piece of T-SQL code that uses DMV&#8217;s (Dynamic Management Views) to give an <em>approximate </em>row count of every table in your database in virtually no time at all. Bear in mind it is running off collected statistics so won&#8217;t always be 100% accurate &#8211; but it&#8217;s far quicker than doing a Count(*) on a table by table basis when you just need a rough idea when doing sizing. In case you don&#8217;t know what DMV&#8217;s there are, go poke around in SSMS &#8211; [Database] &gt; Views &gt; System Views and see what&#8217;s there. Anyway, the code:</p>
<pre><span style="color: #0000ff;">SELECT</span>    s.[Name] as [Schema]
,        t.[name] as [Table]
,        <span style="color: #ff00ff;">SUM</span>(p.rows) as [RowCount]

<span style="color: #0000ff;">FROM</span> <span style="color: #339966;">sys.schemas</span> s
<span style="color: #808080;">LEFT JOIN</span> <span style="color: #339966;">sys.tables</span> t
<span style="color: #0000ff;">ON</span> s.<span style="color: #ff00ff;">schema_id</span> = t.<span style="color: #ff00ff;">schema_id</span>

<span style="color: #808080;">LEFT JOIN</span> <span style="color: #339966;">sys.partitions</span> p
<span style="color: #0000ff;">ON</span> t.<span style="color: #ff00ff;">object_id</span> = p.<span style="color: #ff00ff;">object_id</span>

<span style="color: #808080;">LEFT JOIN</span>  <span style="color: #339966;">sys.allocation_units</span> a
<span style="color: #0000ff;">ON</span>  p.partition_id = a.container_id

<span style="color: #0000ff;">WHERE</span>    p.index_id  in(0,1) <span style="color: #339966;">-- 0 heap table , 1 table with clustered index</span>
<span style="color: #808080;">AND</span>        p.rows is not null
<span style="color: #808080;">AND</span>        a.type = 1  <span style="color: #339966;">-- row-data only , not LOB</span>

<span style="color: #0000ff;">GROUP BY</span> s.[Name], t.[name]
<span style="color: #0000ff;">ORDER BY</span> 1,2</pre>
<p>For a very swift explanation &#8211; <span style="color: #339966;">sys.schemas</span> and <span style="color: #339966;">sys.tables</span> list the schemas and tables in the database, so joining these together on <span style="color: #ff00ff;">schema_id</span> gives a list of all tables by schema in the database. Adding on <span style="color: #339966;">sys.partitions</span> then pulls in the partitions associated with each table, and finally <span style="color: #339966;">sys.allocation_units</span> pulls in the allocation units, which i&#8217;m not quite sure what they are &#8211; the guts of this query were pulled from another blog which I embarrasingly can&#8217;t trace back to now.</p>
<p>I&#8217;m no expert on DMV&#8217;s so if you have any views on the quality of this query &#8211; please leave a comment with your thoughts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bimonkey.com/2009/06/count-the-number-of-rows-in-every-table-in-a-database-in-no-time/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

