<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Jeremiah Peschka » syndication</title>
	
	<link>http://facility9.com</link>
	<description>Jeremiah Peschka's ruminations on sql, ruby, c#, and other things</description>
	<lastBuildDate>Thu, 29 Jul 2010 13:00:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/facility9_syndication" /><feedburner:info uri="facility9_syndication" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Finding Cross-Database Dependencies</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/2Ntnw6Mtn70/finding-cross-database-dependencies</link>
		<comments>http://facility9.com/2010/07/27/finding-cross-database-dependencies#comments</comments>
		<pubDate>Tue, 27 Jul 2010 13:00:20 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[syndication]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1707</guid>
		<description><![CDATA[Ever want to know how many queries are referring to other databases on a server? How about a different server?
Worry no more! I have a query that will help you answer these pesky questions:

SELECT  DB_NAME() AS current_db_name,
        OBJECT_NAME(referencing_id) AS o_name ,
       [...]]]></description>
			<content:encoded><![CDATA[<p>Ever want to know how many queries are referring to other databases on a server? How about a different server?</p>
<p>Worry no more! I have a query that will help you answer these pesky questions:</p>
<pre class="brush:tsql">
SELECT  DB_NAME() AS current_db_name,
        OBJECT_NAME(referencing_id) AS o_name ,
        UPPER(COALESCE(sed.referenced_server_name, '')) AS referenced_server_name,
        sed.referenced_database_name,
        sed.referenced_schema_name,
        sed.referenced_entity_name
FROM    sys.sql_expression_dependencies AS sed
WHERE   referenced_database_name &lt;&gt; DB_NAME()
        AND referenced_database_name &lt;&gt; 'msdb'
ORDER BY UPPER(referenced_server_name) ;
</pre>
<p>Want to run it across every database on your server? We got that, too.</p>
<pre class="brush:tsql">DECLARE @command AS NVARCHAR(MAX);

SET @command = 'USE ?;

SELECT  DB_NAME() AS current_db_name,
        OBJECT_NAME(referencing_id) AS o_name ,
        UPPER(COALESCE(sed.referenced_server_name, '''')) AS referenced_server_name,
        sed.referenced_database_name,
        sed.referenced_schema_name,
        sed.referenced_entity_name
FROM    sys.sql_expression_dependencies AS sed
WHERE   referenced_database_name &lt;&gt; DB_NAME()
        AND referenced_database_name &lt;&gt; ''msdb''
ORDER BY UPPER(referenced_server_name) ;'

EXEC sys.sp_MSforeachdb @command1 = @command</pre>
<p><strong>Update:</strong> This only applies to SQL Server 2008. Nothing else. Thanks to an <a href='http://twitter.com/jjakubowski'>astute reader</a> I have been corrected. Now we&#8217;re all smarter. Thanks, John. <img src='http://facility9.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=2Ntnw6Mtn70:Ph_1zoSQYZ8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=2Ntnw6Mtn70:Ph_1zoSQYZ8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=2Ntnw6Mtn70:Ph_1zoSQYZ8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=2Ntnw6Mtn70:Ph_1zoSQYZ8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=2Ntnw6Mtn70:Ph_1zoSQYZ8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=2Ntnw6Mtn70:Ph_1zoSQYZ8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=2Ntnw6Mtn70:Ph_1zoSQYZ8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=2Ntnw6Mtn70:Ph_1zoSQYZ8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=2Ntnw6Mtn70:Ph_1zoSQYZ8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=2Ntnw6Mtn70:Ph_1zoSQYZ8:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/2Ntnw6Mtn70" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/07/27/finding-cross-database-dependencies/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/07/27/finding-cross-database-dependencies</feedburner:origLink></item>
		<item>
		<title>Revisiting Lady MacBeth and Her Torturous Lies</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/ArJzkHTR3qo/revisiting-lady-macbeth-and-her-torturous-lies</link>
		<comments>http://facility9.com/2010/07/20/revisiting-lady-macbeth-and-her-torturous-lies#comments</comments>
		<pubDate>Tue, 20 Jul 2010 15:13:30 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[syndication]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[sqljackass]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1701</guid>
		<description><![CDATA[A while back, I wrote up a genius piece of code that would automatically shrink my log files whenever they grew.
Kendra Little (blog &#124; twitter) completely called me out for my horrible, sneaky, developer ways. Ostensibly, I had found a solution for my rampant log growth problem. Unfortunately, I had cured the symptom and not [...]]]></description>
			<content:encoded><![CDATA[<p>A while back, I wrote up a <a href='http://facility9.com/2010/06/17/shrink-damnd-log-shrink-i-say' target='_blank'>genius piece of code</a> that would automatically shrink my log files whenever they grew.</p>
<p>Kendra Little (<a href='http://littlekendra.com/' target='_blank'>blog</a> | <a href='http://twitter.com/kendra_little' target='_blank'>twitter</a>) completely called me out for my horrible, sneaky, developer ways. Ostensibly, I had found a solution for my rampant log growth problem. Unfortunately, I had cured the symptom and not the underlying issue. After growing tired of her savage abuse and criticism via gtalk, I looked for the source of the problem. No, not me. The other source of the problem.</p>
<p>I set up monitoring on the server in question, waited for the appropriate log death window, and then read my report. Before you think I&#8217;m using fancy tools that nobody can afford, I set up profiler and perfmon and then merged the results together.</p>
<p>The reports from the single server showed me&#8230; nothing, really. There was a lot of I/O and a backup job overlapped with a re-index by about 2 minutes. The logs also didn&#8217;t fill up. To be on the safe side, I adjusted the jobs and then sat around making frowny faces for a few minutes. Then I remembered that all of the servers are connected to the same SAN, so set up monitoring on the remaining production servers. An I/O issue on one server could start causing problems on all of the other servers.</p>
<p>This time around, the logs filled up, I received a ton of emails, and I also found out something important: all of my backups and re-indexing operations were running at the same time. My SAN was saturated on I/O throughput which was causing a the backup and re-indexing jobs to run slowly. </p>
<p>To solve the problem I looked at the average job run times and arranged the jobs so that they had much more downtime between them (to account for other issues that could slow down the jobs). This took a bit more effort than I thought just because of SLAs within the company. I also re-wrote the jobs so that the backups and re-indexes could never run at the same time and would, instead, occur in series. Once I had this change in place I waited and watched.</p>
<p>Sure enough, the incredible ever growing log file problem stopped happening (unless I do something dumb like move 30,000,000 rows of data). Moral of the story: make sure that you&#8217;re addressing the cause of the problem and not the symptoms.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=ArJzkHTR3qo:F2GVqNa89eY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=ArJzkHTR3qo:F2GVqNa89eY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=ArJzkHTR3qo:F2GVqNa89eY:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=ArJzkHTR3qo:F2GVqNa89eY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=ArJzkHTR3qo:F2GVqNa89eY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=ArJzkHTR3qo:F2GVqNa89eY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=ArJzkHTR3qo:F2GVqNa89eY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=ArJzkHTR3qo:F2GVqNa89eY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=ArJzkHTR3qo:F2GVqNa89eY:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=ArJzkHTR3qo:F2GVqNa89eY:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/ArJzkHTR3qo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/07/20/revisiting-lady-macbeth-and-her-torturous-lies/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/07/20/revisiting-lady-macbeth-and-her-torturous-lies</feedburner:origLink></item>
		<item>
		<title>The Future of Databases</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/HsfZ2vGj9YM/the-future-of-databases</link>
		<comments>http://facility9.com/2010/07/15/the-future-of-databases#comments</comments>
		<pubDate>Thu, 15 Jul 2010 13:00:57 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[nosql_syndication]]></category>
		<category><![CDATA[syndication]]></category>
		<category><![CDATA[olap]]></category>
		<category><![CDATA[oltp]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1652</guid>
		<description><![CDATA[The Story So Far
I&#8217;ve been in love with data storage since I first opened up SQL*Plus and issued a select statement. The different ways to store data are fascinating. Even within a traditional OLTP database, there are a variety of design patterns that we can use to facilitate data access. We keep coming up with [...]]]></description>
			<content:encoded><![CDATA[<h3 id="the_story_so_far">The Story So Far</h3>
<p>I&#8217;ve been in love with data storage since I first opened up <a href="http://en.wikipedia.org/wiki/SQL*Plus">SQL*Plus</a> and issued a select statement. The different ways to store data are fascinating. Even within a traditional OLTP database, there are a variety of design patterns that we can use to facilitate data access. We keep coming up with different ways to solve the problems what we&#8217;re facing in business. The problem is that as the field of computer science advances, and businesses increase in complexity, the ways that we store data must become more complex as well. Exponentially scaling storage complexity isn&#8217;t something that I like to think about, but it&#8217;s a distinct possibility.</p>
<p>General purpose OLTP databases are not the future of data storage and retrieval. They are a single piece in the puzzle. We&#8217;ve been working with OLTP systems for well over 20 years. OLAP is a newer entry, bringing specialized analytical tricks (which are counter intuitive to the way relational data is stored) to the masses. Hell, there are a number of <a href="http://www.microsoft.com/sqlserver/2008/en/us/analysis-services.aspx">general</a> <a href="http://www.oracle.com/technology/products/bi/olap/index.html">purpose</a> <a href="http://www.greenplum.com/">analytical</a> storage engines on the market. These general purpose analytical databases integrate well with existing databases and provide a complement to the transactional specialization of OLTP systems.</p>
<p>That&#8217;s the key, OLTP databases are purpose built <em>transactional</em> databases. They&#8217;re optimized for write operations because way back in the <a href="http://portal.acm.org/citation.cfm?id=362685">dark ages</a> it was far more expensive to write data to disk than it was to read from disk. Data couldn&#8217;t be cached in memory because memory was scarce. Architectural decisions were made. The way that we <a href="http://en.wikipedia.org/wiki/Database_normalization">design our databases</a> is specifically designed to work within this structure. A well designed, normalized, database has minimal duplication of data. In OLTP systems this also serves to minimize the number of writes to disk when a common piece of data needs to be changed. I can remember when I was a kid and the United States Postal Service changed from using three letter state abbreviations to two letter abbreviations. I have to wonder what kind of difficulties this caused for many databases&#8230; </p>
<p>In the 40 years since <a href="http://portal.acm.org/citation.cfm?id=362685">E.F. Codd&#8217;s paper</a> was published, the programming languages that we use have changed considerably. In 1970, COBOL was still relatively new. 1971 saw the the introduction of C, 1975 brought us MS Basic. 1979, 1980, and 1983 saw Ada, Smalltalk-80, Objective-C, and C++ ushering in a wave of object oriented languages. Suddenly programmers weren&#8217;t working on singular data points, they were working with a object that contained a collection of properties. The first ANSI SQL standard was codified in 1986. 1990 gave us Windows 3 and the desktop PC became more than a blinking cursor. The web exploded in 1996, 2001, and continues to explode again in a frenzy of drop shadows, bevels, mirror effects, and Flash.</p>
<p>Throughout the history of computing, we&#8217;ve been primarily working with tuples of data &#8211; attributes mapped to values; rows to you and I. This model holds up well when we&#8217;re working with a entity composed of a single tuple. What happens, though, when the entity becomes more complex? The model to retrieve and modify the entity becomes more complex as well. We can&#8217;t issue a simple update statement anymore, we have to go through more complex operations to make sure that the data is kept up to date.</p>
<h3 id="examples_should_make_things_clearer">Examples Should Make Things Clearer</h3>
<p>Let&#8217;s take a look at something simple: my phone bill.</p>
<h4 id="in_the_beginning8230">In the beginning&#8230;</h4>
<p>Long ago, a phone bill was probably stored in a relatively simple format:</p>
<ul>
<li>Account Number</li>
<li>Name</li>
<li>Address</li>
<li>Past Due Amount</li>
<li>Current Amount Due</li>
<li>Due Date</li>
</ul>
<p>This was simple and it worked. Detailed records would be kept on printed pieces of paper in a big, smelly, damp basement where they could successfully grow mold and other assorted fungi. Whenever a customer had a dispute, a clerk would have to visit the records room and pull up the customer&#8217;s information. This was a manual process that probably involved a lot of letter writing, cursing, and typewriter ribbon.</p>
<p>Eventually, this simple bill format would prove to be unreliable (P.S. I&#8217;m totally making this up just to illustrate a point, but I&#8217;m guessing it went something like this). In our example, there&#8217;s no way to tell when a customer paid or which customer was billed. </p>
<h4 id="after_some_tinkering8230">After some tinkering&#8230;</h4>
<p>After a few more iterations, you probably end up with a way of storing a customer&#8217;s information and bills that looks something like this:</p>
<p>
<a href="http://facility9.com/files/2010/07/The-New-Bill.png"><img src="http://facility9.com/files/2010/07/The-New-Bill.png" alt="" title="A more complex bill hang-2-column" width="528" height="335" class="alignnone wp-image-1653" /></a></p>
<p>This is a lot more complicated from both a design perspective and an implementation perspective. One of the things that makes this implementation more difficult is that there are a number of intermediate tables to work with and these tables can become hotspots for reads as well as writes.</p>
<p>When you look at that design, be honest with yourself and answer this question:</p>
<blockquote>
<p>How often will you view a single service history or general charge row?</p>
</blockquote>
<p>Think about your answer. The fact is, you probably won&#8217;t read any of those rows on its own. You might update one if a change comes in from an external source, but otherwise all of the charges, history, etc on any given phone bill will always be read as a unit. In this particular instance, we&#8217;re always consuming a bill&#8217;s entire <a href="http://en.wikipedia.org/wiki/Graph_(data_structure">graph</a>) at once. Reading a bill into memory is an onerous prospect, not to mention that summarizing phone bills in this system is a read intensive operation.</p>
<h3 id="fixing_the_glitch">Fixing the glitch</h3>
<p>There are a lot of ways these problems could be worked around in a traditional OLTP database. However, that&#8217;s not the point. The point is that there are problems that require actual workarounds. OLTP databases work well for many use cases, but in this case an OLTP database becomes a problem because of the high cost of reading vs writing. (Why should we read-optimize a system that was designed to be write-optimized  when writes will probably account for only 10% of our activity, maybe less?)</p>
<p>I&#8217;ve hinted at how we fix the glitch at the beginning of this article &#8211; we look for a specialized database. In our case, we can use something called a <a href="http://en.wikipedia.org/wiki/Document-oriented_database">document database</a>. The advantage of a document database is that we&#8217;re storing an organized collection of values in the database. This collection of values is similar to a traditional tabular database &#8211; we have groups of similar data stored in named collections. The distinction comes in how the data is accessed. </p>
<p>When we&#8217;re saving a phone bill, we don&#8217;t have to worry about calling multiple stored procedures or a single complex procedure. There&#8217;s no need to create complex mappings between a database and our code. We create an object or object graph in the application code and save it. The software that we use to connect to our document database knows how to properly translate our fancy objects into data stored on a disk somewhere.</p>
<p>This solution has several upsides:</p>
<ul>
<li>Related data is stored in close proximity on disk</li>
<li>Documents do not require strict structure</li>
<li>Documents may change properties without requiring complex changes to physical schema</li>
</ul>
<h4 id="physical_proximity">Physical Proximity</h4>
<p>My data is close together, so what?</p>
<p>In a traditional OLTP database, your data may be scattered across one or multiple disk drives. Physical drive platters will have to spin to locate the data on different parts of your storage medium. Drive read/write arms will have to move around in coordination with the spinning platters. The more complex your query, the more complex the dance your physical hardware will have to do; a simple high school slow dance turns into a tango.</p>
<p>In a document database, all of our data is stored together in a single record. When we want to read our bill, we just have to start reading at the beginning of the bill record and stop when we come to the end. There&#8217;s no need to seek around on the disk.</p>
<p>You might be worried that all of your data won&#8217;t be close together on disk. And you&#8217;d be right. However, many databases (including MongoDB) allow for the creation of secondary indexes to speed up data retrieval. The biggest question you need to ask yourself is &#8220;How will the applications be accessing the data?&#8221; In many applications we&#8217;re only acting on a single object. Even when our application isn&#8217;t acting on a single object, we can pre-aggregate the data for faster reporting and retrieval. When our application only works on a single object at a time, a document database provides distinct advantages &#8211; every time we need an object, we&#8217;ll be pulling back all of the data we need in a single read operation.</p>
<h4 id="strict_structure">Strict Structure</h4>
<p>Databases typically require data to be rigidly structured. A table has a fixed set of columns. The datatypes, precision, and nullability can vary from column to column, but every row will have the same layout. Trying to store wildly diverse and variable data in a fixed storage medium is difficult. </p>
<p>Thankfully, document databases are well-suited to storing semi-structured data &#8211; since our data is a collection of attributes, it&#8217;s very easy to add or remove new attributes and change querying strategies rapidly and in response to different data structure. Better yet, document databases let us be ignorant of how the data is stored. If we want to find all bills where the account holder&#8217;s last name is &#8216;Smith&#8217; and they live in Virginia but the bill doesn&#8217;t have any county tax charges, it is very easy compared to constructing the query in a typical SQL database.</p>
<p>Using <a href="http://mongodb.org">MongoDB</a> our query might look like:</p>
<pre class="brush:tsql">db.bills.find( { last_name : 'Smith' },
               { state : 'Virginia' },
               { charges : { type : 'county tax',
                             $exists : false } } )
</pre>
<p>Compared to similar SQL:</p>
<pre class="brush:tsql">SELECT  b.*
FROM    bills b
        JOIN accounts a ON b.account_id = a.id
        LEFT JOIN charges c ON b.id = c.bill_id
                               AND c.type = 'county tax'
WHERE   a.last_name = 'Smith'
        AND a.state = 'Virginia'
HAVING  COUNT(c.id) = 0
</pre>
<p>And right about now, every DBA that reads this blog is going to be shaking with rage and yelling &#8220;But that SQL is perfectly clear, I don&#8217;t know how you can expect me to understand all of those curly brackets!&#8221; I don&#8217;t expect you to understand those curly brackets. Nor do I expect developers to understand SQL. The easiest way for us to develop is to use our natural paradigm. That&#8217;s why developers write code in C#, PHP, or Ruby and DBAs do their work in some dialect of SQL. MongoDB alleviates this because all the developers are doing is constructing a list of keys and values that must be matched before a document can be returned.</p>
<h4 id="changing_the_schema">Changing the Schema</h4>
<p>Changing the schema of an OLTP database can be an onerous task. You have to wait for, or schedule, down time. Modifications have to take place. Of course, the schema modifications need to take into account any actions (like triggers or replication) that may occur in the background. This alone can require significant skill and internal database engine knowledge to write. It&#8217;s not something that application developers should be expected to know. Why do I mention application developers? 99 times out of 100, they&#8217;re the ones who are working on the database, not a dedicated DBA.</p>
<p>Many newer, non-traditional, databases make it incredibly easy to change the schema &#8211; just start writing the new attribute. The database itself takes care of the changes and will take that into account during querying. When a query is issued for a new attribute, records without that attribute will be ignored (just like a column with a NULL value in a traditional database).</p>
<h3 id="what_about_analytics">What about Analytics?</h3>
<p>I don&#8217;t know a lot about analytical databases, in part because they require a different skill set than the one I&#8217;ve developed. I do know a few things about them, though.</p>
<p>Analytical databases are currently encumbered by some of the same problems as OLTP databases &#8211; data is stored in tables made up of rows and columns. Sure, these are called dimensions/facts and attributes, but the premise is the same &#8211; it&#8217;s a row-based data store.</p>
<p>Row-based data stores pose particular problems for analytic databases. Analytic databases throw most of the rules about normalization in the garbage and instead duplicate data willy nilly. Without joins, it&#8217;s very quick to query and aggregate data. But the problem still remains that there is a large quantity of repeated data being stored on disk.</p>
<p><a href="http://wiki.toadforcloud.com/index.php/Survey_distributed_databases#Columnar_Databases">Columnar databases</a> attempt to solve this problem by compressing columns with similar values and using some kind of magical method to link up columnar values with their respective rows. Sounds complicated, right? Well, it probably is. Let&#8217;s say you have a table with 10,000,000,000 rows and the CalendarYear column is a CHAR(4). If there are only 25 different values for CalendarYear in the database, would you rather store 40,000,000,000 bytes of data or 100 bytes of data? I know which makes more sense to me.</p>
<p>Interestingly enough, there are two approaches being taken to solving this problem. The first is by creating single-purpose columnar databases. There are <a href="http://www.sybase.com/products/datawarehousing/sybaseiq">several</a> <a href="http://infinidb.org/">vendors</a> providing dedicated columnar databases. Other database developers are looking for ways to leverage their <a href="http://blog.tapoueh.org/char10.html#sec10">existing database engines</a> and create hybrid row and columnar databases.</p>
<h3 id="looking_into_the_future">Looking Into the Future</h3>
<p>There are a lot of interesting developments going on in the database world. Many of them seem to be happening outside of the big vendor, traditional database space. Most of this work is being done to solve a particular business need. These aren&#8217;t the traditional row-based OLTP systems that we&#8217;re all familiar with from the last 30 years of database development. These are new, special purpose, databases. It&#8217;s best to think of them like a sports car or even a race car &#8211; they get around the track very quickly, but they would be a poor choice for getting your groceries.</p>
<p>The next time you start a new project or plan a new server deployment, think about what functionality you need. Is it necessary to have full transactional support? Do you need a row-based store? How will you use the data?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=HsfZ2vGj9YM:RRM303KdyIQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=HsfZ2vGj9YM:RRM303KdyIQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=HsfZ2vGj9YM:RRM303KdyIQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=HsfZ2vGj9YM:RRM303KdyIQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=HsfZ2vGj9YM:RRM303KdyIQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=HsfZ2vGj9YM:RRM303KdyIQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=HsfZ2vGj9YM:RRM303KdyIQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=HsfZ2vGj9YM:RRM303KdyIQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=HsfZ2vGj9YM:RRM303KdyIQ:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=HsfZ2vGj9YM:RRM303KdyIQ:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/HsfZ2vGj9YM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/07/15/the-future-of-databases/feed</wfw:commentRss>
		<slash:comments>16</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/07/15/the-future-of-databases</feedburner:origLink></item>
		<item>
		<title>The Board of Directors and You</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/T1ZunmrgBm8/the-board-of-directors-and-you</link>
		<comments>http://facility9.com/2010/07/13/the-board-of-directors-and-you#comments</comments>
		<pubDate>Tue, 13 Jul 2010 13:00:31 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[sqlpass]]></category>
		<category><![CDATA[syndication]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1675</guid>
		<description><![CDATA[The deadline for nominations to the PASS Board of Directors is rapidly approaching. I figured that it would be great if I chimed in and mentioned what I&#8217;ve learned on the Board, what I think would be typical for a board member, and&#8230; I don&#8217;t know what else, but I really felt that this list [...]]]></description>
			<content:encoded><![CDATA[<p>The deadline for <a href='http://www.linkedin.com/redirect?url=http%3A%2F%2Fwww%2Esqlpass%2Eorg%2FCommunity%2FPASSBlog%2Fentryid%2F121%2FCall-for-Nominations-for-2011-2012-PASS-Board-Term-Now-Open%2Easpx&amp;urlhash=tViC' target='_blank'>nominations to the PASS Board of Directors</a> is rapidly approaching. I figured that it would be great if I chimed in and mentioned what I&#8217;ve learned on the Board, what I think would be typical for a board member, and&#8230; I don&#8217;t know what else, but I really felt that this list needed a third item. Mainly because I wanted to show off that I know how to properly use an Oxford comma.</p>
<h3 id="what_is_expected">What Do These People Want From Me?!</h3>
<p>When I stepped up and ran for the PASS Board of Directors, I had no idea what I was doing. I knew that I wanted to help make PASS better. Better how? I had a few ideas. We were going to change the world! There would be speaker mentoring and education for all! A chicken in every garage and mittens on our feet! It turns out that my chickens and mittens proposal isn&#8217;t going so well, but we&#8217;re working on a speaker mentoring program and I&#8217;ve been working with Microsoft to get your feedback to them about certifications.</p>
<p>Enough about me! More about you!</p>
<h4 id="have_a_plan">Have a Plan</h4>
<p><a href="http://www.flickr.com/photos/kyle_slushey_is_awesome/3702677032/" title="This is the future, kid"><img src="http://farm4.static.flickr.com/3612/3702677032_573faa5219_m.jpg" width="240" height="181" alt="KPBB-12" class="alignright"></a>So, this Board of Directors thing, you should have a strong idea of what you would like to change. That could be changes to how we&#8217;re governed, increasing our revenue streams, or finding a new Summit location. The point is that you should have a vision of the future. Beyond a vision, it would be helpful if you have some ideas about how you&#8217;re going to fulfill that vision. You don&#8217;t need to have a complete business plan, although that never hurts.</p>
<p>I can&#8217;t stress how important having a strong vision is. The goal is to have Board members act in a strategic role. Rather than plan things <em>and</em> implement them, you should be coming up with broad plans. Once you&#8217;ve come up with plans and goals you&#8217;ll work with PASS HQ and a few key volunteers to implement things. That isn&#8217;t always how things work out, but that should be the goal.</p>
<p>Without a strong vision, it&#8217;s very easy to get swept along. This is a two year commitment. if you&#8217;re being swept along for two years, you&#8217;re going to feel very lost, purposeless, and burnt out. Make sure that you know you have something that you plan to accomplish. When you&#8217;re finished with your term you can look back and say &#8220;I did <em>that</em> and I&#8217;m damn proud of it.&#8221; I know that when I&#8217;m done, we will have happily gone through and codified and documented more of the abstract selection process. There will be less tribal knowledge and more of it will be available for easy public consumption.  I&#8217;m going to be happy about that. Know what you&#8217;re doing. Have a goal, make a plan. Don&#8217;t be afraid to revise it.</p>
<h4 id="the_time_of_your_life">The Time of Your Life</h4>
<p><a href="http://www.flickr.com/photos/blackcustard/247625993/" title="Pinhole: Clock by Matt Callow, on Flickr"><img src="http://facility9.com/files/2010/07/247625993_2603011c36_o.jpg" alt="Pinhole: Clock" title="247625993_2603011c36_o" width="640" height="134" class="aligncenter size-medium wp-image-1676" /></a></p>
<p>People always say that you need to be willing to donate &#8220;a few hours a week&#8221; of your time if you want to be on the PASS Board of Directors. (They say this for just about anything else, too.) So, how much time does it really require?</p>
<p>That all depends on how much work you take on, how much you can delegate, and your own personal comfort level. The amount of time that I spend on my own portfolio is not typical &#8211; that&#8217;s not to say that they work less, it&#8217;s just that my time commitments come in spikes where I&#8217;ll be incredibly busy for three or four months and then a lot of the year things are very quiet. I&#8217;m hoping that other Board members will comment here and put forward their opinions and help to add to this article and clear things up for the people who are thinking about running for the Board of Directors. The point is: there&#8217;s no fixed amount of time. It&#8217;s as much or as little time as you want to put into it.</p>
<p>There&#8217;s a one hour conference call once a month. As often as once a quarter there will be an in-person Board meeting. You&#8217;ll typically spend a day traveling to and from the meeting and two days on site. This ends up being four week days, in my experience. Of course, one of these in person Board meetings ends up being the PASS Community Summit. So that&#8217;s one less week that you have to take off from work.</p>
<h4 id="skills_in_magic">Skills in Magic</h4>
<p><a href="http://www.flickr.com/photos/iamagenious/4009214094/" title="hella dope  by permanently scatterbrained, on Flickr"><img src="http://facility9.com/files/2010/07/4009214094_6f4371c4b8_z.jpg" alt="hella dope" title="hella dope" width="170" height="362" class="hang-2-column size-full wp-image-1677" /></a></p>
<p>What kind of skills do you need to be on the PASS Board of Directors? We&#8217;ve already covered one: planning. You should be reasonably good at planning. You don&#8217;t need to be a genius strategist, but you should be able to put together a simple plan and execute on it. These are the skills that you&#8217;ve built as a DBA or database developer. You know how to make a list, prioritize, delegate, and execute on that list. If you can do that effectively, you&#8217;re halfway there.</p>
<p>The other skills that you would use in running a business the size of PASS&#8230; it would help if you had them before starting, but they&#8217;re not necessary.</p>
<h3 id="the_free_mba">The Free MBA</h3>
<p>The PASS Board of Directors is the cheapest and most entertaining MBA program I have found. Nowhere else will you find the opportunity to manage a 7 figure budget while dining on bacon.</p>
<p>You can quote me on that.</p>
<p>One of the greatest things about the PASS Board of Directors is that it really is like an MBA program. I&#8217;ve learned about budgeting on a 7 figure scale, about how decisions play out, how to think strategically, how to plan, delegate, project, and all of the other things that they talk about in fancy business classes. Instead of one instructor and a few students, you&#8217;re one student with many other instructors. There are five other board members, three members of the Executive Committee, four vendor board members, the immediate past president, and let&#8217;s not forget our non-voting representative from Europe. Right there, you&#8217;re going to be learning from fourteen other people.</p>
<p>In the last seven months, I&#8217;ve learned more about my abilities as a manager than in the rest of my career. I was speaking with a friend recently, and he asked me what I thought about the PASS Board of Directors. Knowing that this friend was in management I said &#8220;It&#8217;s an awful lot like being a manager without the benefit of a company car and a reserved parking space.&#8221; After a hearty chuckle, we proceeded to play golf using a corporate AmEx. Okay, maybe that was a lie. But we did talk about the experience. The one thing that struck me is what I&#8217;ve mentioned here &#8211; it&#8217;s been the greatest education about business and about myself. There are days when I joke that I don&#8217;t know why people complain about being managers, all you do is tell people to do something and wait until they get it done. There are other days when I want to shove my head in a mailbox and scream.</p>
<p>The biggest thing that I&#8217;ve learned is how to listen. I don&#8217;t always see eye-to-eye with my fellow board members. But I&#8217;ve learned to listen to what they&#8217;re saying and to try to understand where they&#8217;re coming from. Sure, we all say things like this, right? That&#8217;s what marriages and friendships are about. When you&#8217;re making large decisions about the PASS Community Summit or a spring event or a budgetary decision, you suddenly realize how little you listened before and how much you need to listen. You want to know something funny? I don&#8217;t find myself agreeing with people any more than I did before I started listening closely, but I do find myself understanding them. That alone has made a huge difference for me professionally and personally.</p>
<h3 id="the_round_up">The Round Up</h3>
<p>That&#8217;s not a ringing endorsement, but there are bad days. The good days and the learning experiences far outweigh the bad days and the stress.</p>
<p>In the end, it&#8217;s been worth it. If I had to do it again, would I still run for election? Absolutely.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=T1ZunmrgBm8:Hs6fmqvQreY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=T1ZunmrgBm8:Hs6fmqvQreY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=T1ZunmrgBm8:Hs6fmqvQreY:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=T1ZunmrgBm8:Hs6fmqvQreY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=T1ZunmrgBm8:Hs6fmqvQreY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=T1ZunmrgBm8:Hs6fmqvQreY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=T1ZunmrgBm8:Hs6fmqvQreY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=T1ZunmrgBm8:Hs6fmqvQreY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=T1ZunmrgBm8:Hs6fmqvQreY:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=T1ZunmrgBm8:Hs6fmqvQreY:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/T1ZunmrgBm8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/07/13/the-board-of-directors-and-you/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/07/13/the-board-of-directors-and-you</feedburner:origLink></item>
		<item>
		<title>TFS and You</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/bvpqBAW-nhY/tfs-and-you</link>
		<comments>http://facility9.com/2010/07/07/tfs-and-you#comments</comments>
		<pubDate>Wed, 07 Jul 2010 11:32:50 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[TFS]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[syndication]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1649</guid>
		<description><![CDATA[How many of you are using Visual Studio 2010? How many of you are writing SSIS packages? How many of you are pissed off, irritated, or confused about how you&#8217;ll be able to write and version control your SSIS packages (VS 2008) once you&#8217;ve upgraded to TFS 2010?
Confused yet? Yeah, so am I.
Let&#8217;s backtrack: at [...]]]></description>
			<content:encoded><![CDATA[<p>How many of you are using Visual Studio 2010? How many of you are writing SSIS packages? How many of you are pissed off, irritated, or confused about how you&#8217;ll be able to write and version control your SSIS packages (VS 2008) once you&#8217;ve upgraded to TFS 2010?</p>
<p>Confused yet? Yeah, so am I.</p>
<p>Let&#8217;s backtrack: at work we recently upgraded to VS 2010 and TFS 2010 &#8211; this lets everyone on my team take advantage of the database developer edition as well as add a whole slew of automated testing features and doodads. Plus our management can tie in to our tasks </p>
<p>One of the problems that we ran into is connecting to TFS2010 from VS2008. Why would I need to do that? Visual Studio 2010 doesn&#8217;t have support for the SQL Server 2008 BI project types yet (SSRS, SSIS, etc). So, in order to work on SSIS packages, I need to keep VS 2008 around. </p>
<p>It&#8217;s pretty easy to connect Visual Studio 2008 to TFS 2010. <a href='http://www.microsoft.com/downloads/details.aspx?FamilyID=CF13EA45-D17B-4EDC-8E6C-6C5B208EC54D&amp;displaylang=en'>Download this hotfix</a>, install it, and then you&#8217;re up and running. That&#8217;s really all there is to it.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=bvpqBAW-nhY:u5WkTcvCx0s:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=bvpqBAW-nhY:u5WkTcvCx0s:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=bvpqBAW-nhY:u5WkTcvCx0s:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=bvpqBAW-nhY:u5WkTcvCx0s:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=bvpqBAW-nhY:u5WkTcvCx0s:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=bvpqBAW-nhY:u5WkTcvCx0s:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=bvpqBAW-nhY:u5WkTcvCx0s:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=bvpqBAW-nhY:u5WkTcvCx0s:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=bvpqBAW-nhY:u5WkTcvCx0s:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=bvpqBAW-nhY:u5WkTcvCx0s:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/bvpqBAW-nhY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/07/07/tfs-and-you/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/07/07/tfs-and-you</feedburner:origLink></item>
		<item>
		<title>Using Indexed Views to Replace Triggers</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/br-srIrRUcI/using-indexed-views-to-replace-triggers</link>
		<comments>http://facility9.com/2010/07/01/using-indexed-views-to-replace-triggers#comments</comments>
		<pubDate>Thu, 01 Jul 2010 13:14:11 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[syndication]]></category>
		<category><![CDATA[indexed views]]></category>
		<category><![CDATA[views]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1642</guid>
		<description><![CDATA[Let&#8217;s get this out of the way: I think triggers are cool. I also think triggers have their place, they just need to be used with care. One reason for this is that triggers are synchronous. That is &#8211; trigger actions will block a command from returning to the client until the the trigger&#8217;s actions [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s get this out of the way: I think triggers are cool. I also think triggers have their place, they just need to be used with care. One reason for this is that triggers are synchronous. That is &#8211; trigger actions will block a command from returning to the client until the the trigger&#8217;s actions have completed.</p>
<p>What&#8217;s the solution? Do we run summary jobs on a regular basis? Maybe.</p>
<p>Sometimes summary jobs aren&#8217;t enough. Sometimes we have to update summarized data in real time. Let&#8217;s break out <a href="http://msftdbprodsamples.codeplex.com/" target="_blank">AdventureWorks</a> and look at an example.</p>
<p>Let&#8217;s say we have a report that shows us the total line item sales per customer broken out by year and month.</p>
<p>That&#8217;s pretty simple, right?</p>
<pre class="brush:tsql">
SELECT  p.BusinessEntityID ,
        p.FirstName ,
        p.LastName ,
        DATEPART(yyyy, soh.OrderDate) AS [Year] ,
        DATEPART(mm, soh.OrderDate) AS [Month] ,
        SUM(sod.LineTotal) AS LineItemTotal
FROM    Person.Person AS p
        INNER JOIN Sales.Customer AS c ON c.PersonID = p.BusinessEntityID
        INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID
        INNER JOIN Sales.SalesOrderDetail AS sod ON soh.SalesOrderID = sod.SalesOrderID
GROUP BY p.BusinessEntityID ,
        p.FirstName ,
        p.LastName ,
        DATEPART(yyyy, soh.OrderDate) ,
        DATEPART(mm, soh.OrderDate)
ORDER BY p.BusinessEntityID ,
        [Year] ,
        [Month] ;
</pre>
<p>The problem is that this query may use a lot of CPU or disk resources. How can we avoid that? Earlier I mentioned using summary jobs. The problem is that the summary jobs will only run on a schedule and require that we maintain some kind of maintenance history of each row &#8211; even if that maintenance history is just a modification timestamp. Wouldn&#8217;t it be easier if our summary report just updated itself automagically?</p>
<p>It can! Enter the indexed view.</p>
<p>An indexed view is a regular view that has a clustered index on it. By adding the clustered index the view is persisted to disk. The upside of persisting the indexed view to disk is that there&#8217;s an automatic mechanism in place that will update the indexed view. An indexed view must have a unique clustered index so that SQL Server can identify the materialized row that must be updated in response to changes in the underlying data.</p>
<pre class="brush:tsql">
CREATE VIEW dbo.my_indexed_view
WITH SCHEMABINDING
AS
  SELECT  p.BusinessEntityID,
          p.FirstName,
          p.LastName,
          DATEPART(yyyy, soh.OrderDate) AS [Year],
          DATEPART(mm, soh.OrderDate) AS [Month],
          SUM(sod.LineTotal) AS LineItemTotal,
          COUNT_BIG(*) AS NumberOfRecords
  FROM    Person.Person AS p
          INNER JOIN Sales.Customer AS c ON c.PersonID = p.BusinessEntityID
          INNER JOIN Sales.SalesOrderHeader AS soh ON c.CustomerID = soh.CustomerID
          INNER JOIN Sales.SalesOrderDetail AS sod ON soh.SalesOrderID = sod.SalesOrderID
  GROUP BY p.BusinessEntityID,
          p.FirstName,
          p.LastName,
          DATEPART(yyyy, soh.OrderDate),
          DATEPART(mm, soh.OrderDate) ;
GO

CREATE UNIQUE CLUSTERED INDEX CX_my_indexed_view ON dbo.my_indexed_view (BusinessEntityID, [Year], [Month]) ;
</pre>
<p>We <strong>could</strong> have accomplished this using a summary table and triggers. Triggers are synchronous and updating the summary table will block our data changes from completing. In addition, if we ever want to bypass the trigger from updating (say during a huge data load) we need to disable and then enable the trigger again and then remember to update the summary table. With an indexed view we can just drop the clustered index and then recreate it when we&#8217;re done with our load processes.</p>
<p><em>Note:</em> I can&#8217;t take full credit for this question and explanation. A SQL Saturday #42 attendee sent me an email with a question about using indexed views instead of triggers.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=br-srIrRUcI:54RUjz7zSTo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=br-srIrRUcI:54RUjz7zSTo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=br-srIrRUcI:54RUjz7zSTo:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=br-srIrRUcI:54RUjz7zSTo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=br-srIrRUcI:54RUjz7zSTo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=br-srIrRUcI:54RUjz7zSTo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=br-srIrRUcI:54RUjz7zSTo:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=br-srIrRUcI:54RUjz7zSTo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=br-srIrRUcI:54RUjz7zSTo:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=br-srIrRUcI:54RUjz7zSTo:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/br-srIrRUcI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/07/01/using-indexed-views-to-replace-triggers/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/07/01/using-indexed-views-to-replace-triggers</feedburner:origLink></item>
		<item>
		<title>SQL Saturday 42 Musings</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/dl0Mr6Slfx0/sql-saturday-42-musings</link>
		<comments>http://facility9.com/2010/06/29/sql-saturday-42-musings#comments</comments>
		<pubDate>Tue, 29 Jun 2010 11:28:55 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Speaking]]></category>
		<category><![CDATA[sqlpass]]></category>
		<category><![CDATA[syndication]]></category>
		<category><![CDATA[presenting]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[sqlsaturday]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1644</guid>
		<description><![CDATA[SQL Saturday 42 has been and gone. I don&#8217;t have a ton to say, but I wanted to try to post my thoughts on the event before they were completely gone from my mind.
The people who put this event on &#8211; Dave Schutz, Stuart Johnson, Marc Kuyper, Jim Stoltz, and John Jakubowski &#8211; deserve a [...]]]></description>
			<content:encoded><![CDATA[<p>SQL Saturday 42 has been and gone. I don&#8217;t have a ton to say, but I wanted to try to post my thoughts on the event before they were completely gone from my mind.</p>
<p>The people who put this event on &#8211; Dave Schutz, Stuart Johnson, Marc Kuyper, Jim Stoltz, and John Jakubowski &#8211; deserve a big round of applause. They put together a very strong event and it seemed like they were incredibly well prepared.</p>
<p>Despite Brent Ozar suffering from incredible jet lag, and another speaker not showing up, things went off well. Allen White and I were able to cover Brent&#8217;s time slots, but not his presentations. This led to the funny moment of an attendee walking into the room and saying &#8220;You&#8217;re not Brent Ozar.&#8221; I replied, &#8220;No, I am not, but I&#8217;m talking about SQL Server Internals, it&#8217;ll be fun.&#8221; They just said, &#8220;Oh,&#8221; and walked away. So, apparently, I&#8217;m nowhere near as engaging as Brent talking about his stupid and dangerous T-SQL tricks. Clearly they don&#8217;t know that I&#8217;m just stupid and dangerous.</p>
<p>Outside of that, things went very well. My Dynamic SQL talk went over well, although I think I need to re-work it. I felt like I was flipping back and forth between demos and code a bit too much. It gave the entire experience a jerky feel. I suspect I&#8217;m overly critical of the presentation since I&#8217;ve given it a few times, but it&#8217;s always good to improve.</p>
<p>My internals presentation wasn&#8217;t well attended &#8211; this is probably due to me not being Brent Ozar. However, that didn&#8217;t stop us from having fun talking about SQL Server Internals. If anything, having a room of 6 people made the topic more fun to talk about. We were able to digress onto different topics, delve a little bit deeper than normal, and have a lot of fun watching me not trip over an extension cord.</p>
<p>Last but not least was my Indexes and Other Free Performance Boosts. I had a full room on this &#8211; I suspect it had something to do with the word &#8220;Free&#8221; in the presentation title. This is a really fun presentation because it&#8217;s a whirlwind tour of indexes, keys, statistics, and how they work together to coax SQL Server into giving us data faster. Once again, I think I need to smooth up the code samples, but on the whole things went really well. </p>
<p>I don&#8217;t have any of the evaluations, but I hope the SQL Saturday team is able to get those out to the speakers soon. From the ones I glanced at, I did a passable job. I&#8217;m looking forward to the next event in Columbus.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=dl0Mr6Slfx0:IJ3mQHOh1CA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=dl0Mr6Slfx0:IJ3mQHOh1CA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=dl0Mr6Slfx0:IJ3mQHOh1CA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=dl0Mr6Slfx0:IJ3mQHOh1CA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=dl0Mr6Slfx0:IJ3mQHOh1CA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=dl0Mr6Slfx0:IJ3mQHOh1CA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=dl0Mr6Slfx0:IJ3mQHOh1CA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=dl0Mr6Slfx0:IJ3mQHOh1CA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=dl0Mr6Slfx0:IJ3mQHOh1CA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=dl0Mr6Slfx0:IJ3mQHOh1CA:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/dl0Mr6Slfx0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/06/29/sql-saturday-42-musings/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/06/29/sql-saturday-42-musings</feedburner:origLink></item>
		<item>
		<title>Free Training – SQL Saturday 42</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/8l6Z-XMrXdc/free-training-sql-saturday-42</link>
		<comments>http://facility9.com/2010/06/23/free-training-sql-saturday-42#comments</comments>
		<pubDate>Wed, 23 Jun 2010 13:01:36 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Speaking]]></category>
		<category><![CDATA[sqlpass]]></category>
		<category><![CDATA[syndication]]></category>
		<category><![CDATA[dynamic sql]]></category>
		<category><![CDATA[presenting]]></category>
		<category><![CDATA[SQL Saturday]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1640</guid>
		<description><![CDATA[Good news! I&#8217;m speaking at SQL Saturday 42 this Saturday. Got nothing to do? Head on down to Goodwill Columbus at 1331 Edgehill Rd, Columbus, OH. Got something to do? Cancel it.
I&#8217;m excited about the presentations I&#8217;m giving &#8211; I haven&#8217;t given the indexing presentation in a long time and it should be a lot [...]]]></description>
			<content:encoded><![CDATA[<p>Good news! I&#8217;m speaking at <a href='http://sqlsaturday.com/42/eventhome.aspx' target='_blank'>SQL Saturday 42</a> this Saturday. Got nothing to do? Head on down to Goodwill Columbus at 1331 Edgehill Rd, Columbus, OH. Got something to do? Cancel it.</p>
<p>I&#8217;m excited about the presentations I&#8217;m giving &#8211; I haven&#8217;t given the indexing presentation in a long time and it should be a lot of fun. And the Dynamic SQL presentation is one of the first in the day. It&#8217;s a nice easy way (I think) to get your day started. </p>
<h3>A Dynamic World Demands Dynamic SQL</h3>
<p>Dynamic SQL is a misunderstood and much maligned part of a DBA’s tool kit – it can be used to solve difficult business problems, respond to diverse data needs, and alleviate performance problems. Many DBAs reject dynamic SQL outright as a potential source of SQL injections, being poorly performing, or just for being a hacky solution in general. Not so! Jeremiah Peschka has been making extensive use of dynamic SQL throughout his career to solve a variety of problems. He’ll set about dispelling these misconceptions and demonstrate how dynamic SQL can become a part of every DBA’s tool kit.</p>
<h3>Indexes And Other Free Performance Boosts</h3>
<p>The database is often viewed as a major performance bottleneck. There are a number of quick, easy, painless techniques that can increase the performance of an application not just by a small amount, but by orders of magnitude. These techniques includes simple indexing techniques, T-SQL techniques, and general database application design patterns that give great gains in performance. In this session, you will learn how to look at a database to identify these problem areas and how to resolve common issues that you will encounter.</p>
<h3>What else?</h3>
<p>Let&#8217;s say you&#8217;re interested in something else. What should you go see? Well, Michael Swart (<a href='http://michaeljswart.com' target='_blank'>blog</a> | <a href='http://twitter.com/MJSwart' target='_blank'>twitter</a>) put together a nice little blog post about <a href='http://michaeljswart.com/?p=737' target='_blank'>How I plan to spend my weekend</a>.</p>
<p>If you like business intelligence, I suggest you hit up Dave Rodabaugh&#8217;s presentations. I cannot speak highly enough of Dave&#8217;s work. Not only is he one of the brightest BI people I know, he&#8217;s also been a teacher, friend, and mentor to me for a long time.</p>
<p>There will be some kind of dinner/drinks/whatever going on afterwards at <a href='http://www.barleysbrewing.com/' target='_blank'>Barley&#8217;s Smokehouse</a> (<a href='http://maps.google.com/maps?ie=UTF8&amp;q=barleys+near+columbus,+oh&amp;fb=1&amp;gl=us&amp;hq=barleys&amp;hnear=Columbus,+Franklin,+Ohio&amp;ei=CwUiTODhA8OclgfxyI1q&amp;ved=0CDMQtgMwBA&amp;ll=39.966596,-83.0266&amp;spn=0.055323,0.077162&amp;z=14&amp;iwloc=B' target='_blank'>map</a>). I plan on being there for a little bit. Even if you can&#8217;t make it to the event, head on over there around 6:00PM. I&#8217;ll be there. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=8l6Z-XMrXdc:gsN7xpHUo-w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=8l6Z-XMrXdc:gsN7xpHUo-w:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=8l6Z-XMrXdc:gsN7xpHUo-w:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=8l6Z-XMrXdc:gsN7xpHUo-w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=8l6Z-XMrXdc:gsN7xpHUo-w:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=8l6Z-XMrXdc:gsN7xpHUo-w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=8l6Z-XMrXdc:gsN7xpHUo-w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=8l6Z-XMrXdc:gsN7xpHUo-w:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=8l6Z-XMrXdc:gsN7xpHUo-w:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=8l6Z-XMrXdc:gsN7xpHUo-w:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/8l6Z-XMrXdc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/06/23/free-training-sql-saturday-42/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/06/23/free-training-sql-saturday-42</feedburner:origLink></item>
		<item>
		<title>Shrink, Damn’d Log! Shrink, I Say!</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/rDxoBXwZXOM/shrink-damnd-log-shrink-i-say</link>
		<comments>http://facility9.com/2010/06/17/shrink-damnd-log-shrink-i-say#comments</comments>
		<pubDate>Thu, 17 Jun 2010 12:00:05 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[syndication]]></category>
		<category><![CDATA[AppDev]]></category>
		<category><![CDATA[dynamic sql]]></category>
		<category><![CDATA[hackery]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1597</guid>
		<description><![CDATA[Ever have a database log file grow to epic proportions on the weekend? I have. Ever forget to set up job monitoring on that server? I have. Ever get so pissed off that you decided to write a job to automatically shrink the log files whenever they grow? I have.

I used my rudimentary knowledge of [...]]]></description>
			<content:encoded><![CDATA[<p>Ever have a database log file grow to epic proportions on the weekend? I have. Ever forget to set up job monitoring on that server? I have. Ever get so pissed off that you decided to write a job to automatically shrink the log files whenever they grow? I have.</p>
<p><span id="more-1597"></span></p>
<p>I used my rudimentary knowledge of Service Broker, Event Notifications, and hackery to create a solution to my problem. For starters, I added the following stored procedure to every database:</p>
<pre class="brush:tsql">CREATE SCHEMA dba ;
GO

IF OBJECT_ID(N'dba.ShrinkLog', N'P') IS NOT NULL
  DROP PROCEDURE dba.ShrinkLog ;
GO

CREATE PROCEDURE dba.ShrinkLog
  WITH EXECUTE AS OWNER
AS
  BEGIN
    DECLARE @error AS VARCHAR(2000) = 'LOG_FILE_AUTO_GROW encountered' ;
    RAISERROR (@error, 10, 1) WITH LOG

    DECLARE @size_in_mb AS DECIMAL(18, 5) ;
    DECLARE @max_log_size_in_mb AS DECIMAL(18, 5) = 10240 ;

    SELECT  @size_in_mb = ( size * 8.0 ) / 1024.0
    FROM    sys.database_files
    WHERE   data_space_id = 0 ;

    IF @size_in_mb &gt; @max_log_size_in_mb
      BEGIN

        SET @error = 'log shrink occured on ' + DB_NAME() + ' at '
          + CONVERT(VARCHAR(50), GETDATE(), 101) + '. log file was '
          + CAST(@size_in_mb AS VARCHAR(50)) + ' mb in size.' ;

        RAISERROR (@error, 10, 1) WITH LOG

        DBCC SHRINKFILE (2, 1024) ;
      END
  END
GO  </pre>
<p>Once I had my procedure in place, I needed a way to fire this procedure. Rather than mindlessly attempt to shrink the log files every X minutes, I decided that I should only shrink the file after a log growth has occurred. This means that, in theory, I could stop the log from growing&#8230; because, you know, I&#8217;m a bastard. We don&#8217;t want the log to NEVER grow, just shrink when it gets too big &#8211; which is possible because this might be a problem between log backups. That&#8217;s why there&#8217;s a check to see if the log file is greater than an arbitrary maximum size.</p>
<p>The next step was to actually figure out how to make this procedure fire. I wasn&#8217;t sure about it, but I thought that there was a SQL Server Event Notification that would fire whenever the log file grew. Turns out that I was right: <a href='http://msdn.microsoft.com/en-us/library/ms179635.aspx' target='_blank'>LOG_FILE_AUTO_GROW</a>.</p>
<p>Now, I knew from reading <a href='http://weblogs.sqlteam.com/mladenp/archive/2008/07/18/Immediate-deadlock-notifications-without-changing-existing-code.aspx' target='_blank'>Mladen Prajdić&#8217;s blog</a> that I could use the SQL Server Service Broker to respond to system events and, so, I did just that.</p>
<pre class="brush:tsql">USE SystemEvents ;
GO

IF OBJECT_ID(N'dbo.LogShrinkResponse', N'P') IS NOT NULL
  DROP PROCEDURE dbo.LogShrinkResponse ;
GO

CREATE PROCEDURE dbo.LogShrinkResponse
AS
  BEGIN
    DECLARE @msgBody XML
    DECLARE @dlgId UNIQUEIDENTIFIER

  -- you can change this to get all messages at once
    WHILE ( 1 = 1 )
      BEGIN

        BEGIN TRANSACTION ;

        BEGIN TRY 

            ;
          RECEIVE TOP (1)
                @msgBody = message_body,
                @dlgId = conversation_handle FROM LogShrinkNotificationQueue ;

          IF @@ROWCOUNT = 0
            BEGIN
              IF @@TRANCOUNT &gt; 0
                BEGIN
                  ROLLBACK ;
                END

              BREAK ;
            END

          DECLARE @database_name AS SYSNAME ;
          DECLARE @data AS XML ;
          DECLARE @statement AS NVARCHAR(2000) ;

          SET @data = EVENTDATA() ;

          SET @database_name = @data.value('(/EVENT_INSTANCE/DatabaseName)[1]',
                                           'NVARCHAR(128)') ;

          SET @statement = N'USE ' + @database_name
            + '; EXEC dba.ShrinkLog ; '

          EXEC sp_executesql @statement ;

          IF @@TRANCOUNT &gt; 0
            BEGIN
              COMMIT ;
            END
        END TRY

        BEGIN CATCH
          IF @@TRANCOUNT &gt; 0
            BEGIN
              ROLLBACK ;
            END

          -- write any error in to the event log
          DECLARE @errorNumber BIGINT ,
            @errorMessage NVARCHAR(2048) ,
            @dbName NVARCHAR(128)
          SELECT  @errorNumber = ERROR_NUMBER() ,
                  @errorMessage = ERROR_MESSAGE() ,
                  @dbName = DB_NAME()

          RAISERROR (N'Error WHILE receiving Service Broker message FROM queue LogShrinkNotificationQueue.
                        DATABASE Name: %s; Error number: %I64d; Error Message: %s',
            16, 1, @dbName, @errorNumber, @errorMessage) WITH LOG ;
        END CATCH ;
      END
  END
GO

CREATE QUEUE LogShrinkNotificationQueue
WITH STATUS = ON,
ACTIVATION ( PROCEDURE_NAME = dbo.LogShrinkResponse, MAX_QUEUE_READERS = 1, EXECUTE AS 'dbo'
) ;
GO

CREATE SERVICE LogShrinkNotificationService ON QUEUE LogShrinkNotificationQueue
([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]) ;
GO

CREATE ROUTE LogShrinkNotificationRoute
WITH SERVICE_NAME = 'LogShrinkNotificationService',
ADDRESS = 'LOCAL' ;

CREATE EVENT NOTIFICATION LogShrinkNotificationEvent ON SERVER FOR LOG_FILE_AUTO_GROW
TO SERVICE 'LogShrinkNotificationService', 'current database' ;
GO

/*
DROP PROCEDURE dba.ShrinkLog
DROP EVENT NOTIFICATION LogShrinkNotificationEvent ON SERVER
DROP ROUTE LogShrinkNotificationRoute
DROP SERVICE LogShrinkNotificationService
DROP QUEUE LogShrinkNotificationQueue
*/</pre>
<p>Here&#8217;s what&#8217;s going on up there. </p>
<p>We create a procedure that will be called when the log shrink notification is caught. It loops through our queue and grabs the top message off each time and processes it. If there&#8217;s a message, it will pull the name of the database out of the <a href='http://schemas.microsoft.com/sqlserver/' target='_blank'>XML from the event notification</a>. We use the database name to build dynamic SQL that we execute to fire off the log shrink procedure.</p>
<p>The rest of the code just sets up the service broker queue, notification, routing, and event handler. It&#8217;s basic, boiler plate, code that tells SQL Server to set up service broker on the current database and listen for th LOG_FILE_AUTO_GROW event.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=rDxoBXwZXOM:l6QKbqXrrZw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=rDxoBXwZXOM:l6QKbqXrrZw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=rDxoBXwZXOM:l6QKbqXrrZw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=rDxoBXwZXOM:l6QKbqXrrZw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=rDxoBXwZXOM:l6QKbqXrrZw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=rDxoBXwZXOM:l6QKbqXrrZw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=rDxoBXwZXOM:l6QKbqXrrZw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=rDxoBXwZXOM:l6QKbqXrrZw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=rDxoBXwZXOM:l6QKbqXrrZw:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=rDxoBXwZXOM:l6QKbqXrrZw:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/rDxoBXwZXOM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/06/17/shrink-damnd-log-shrink-i-say/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/06/17/shrink-damnd-log-shrink-i-say</feedburner:origLink></item>
		<item>
		<title>T-SQL Tuesday – “Did he just say that?” edition</title>
		<link>http://feedproxy.google.com/~r/facility9_syndication/~3/eQK4xGvT8k0/t-sql-tuesday-did-he-just-say-that-edition</link>
		<comments>http://facility9.com/2010/06/15/t-sql-tuesday-did-he-just-say-that-edition#comments</comments>
		<pubDate>Tue, 15 Jun 2010 12:00:46 +0000</pubDate>
		<dc:creator>Jeremiah Peschka</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[pg_syndication]]></category>
		<category><![CDATA[syndication]]></category>
		<category><![CDATA[AppDev]]></category>

		<guid isPermaLink="false">http://facility9.com/?p=1621</guid>
		<description><![CDATA[As in, I didn&#8217;t participate in the most recent T-SQL Tuesday about my favorite feature in SQL 2008 R2.
Want to know my favorite 2008R2 features? PostgreSQL 9.0 and MongoDB.
PostgreSQL and MongoDB are rapidly advancing features that solve my daily problems. I&#8217;m an OLTP guy. Honestly, I don&#8217;t care about the latest reporting ding dongs and [...]]]></description>
			<content:encoded><![CDATA[<p>As in, I didn&#8217;t participate in the most recent T-SQL Tuesday about my <a href='http://sqlchicken.com/2010/06/t-sql-tuesday-007-summertime-in-the-sql/' target='_blank'>favorite feature in SQL 2008 R2</a>.</p>
<p>Want to know my favorite 2008R2 features? <a href='http://www.postgresql.org/about/news.1210' target='_blank'>PostgreSQL 9.0</a> and <a href='http://mongodb.com/' target='_blank'>MongoDB</a>.</p>
<p>PostgreSQL and MongoDB are rapidly advancing features that solve my daily problems. I&#8217;m an OLTP guy. Honestly, I don&#8217;t care about the latest reporting ding dongs and doo dads. I already know <a href='http://perl.org' target='powershell is perl'>PowerShell</a>. I manage 6 production servers and we&#8217;re unlikely to grow, so these MDM and Utility Control Points don&#8217;t make me giddy with excitement. </p>
<p>I solve problems using SQL.</p>
<p>You know what makes me happy? <a href='http://www.postgresql.org/docs/8.4/interactive/tutorial-window.html' target='_blank'>Support for window functions</a> or better yet, <a href='http://www.depesz.com/index.php/2010/02/17/waiting-for-9-0-extended-frames-for-window-functions/' target='_blank'>improved support for window functions</a>. What about <a href='http://www.pgcon.org/2010/schedule/events/201.en.html' target='_blank'>exclusion constraints</a>? Or column level triggers so I don&#8217;t have to use branching logic in my triggers? Yes, I use triggers. Or any other of <a href='http://www.postgresonline.com/journal/index.php?/archives/164-What-is-new-in-PostgreSQL-9.0.html#extended'>these features</a>.</p>
<p>What about MongoDB? I&#8217;ve just started playing with it, but it solves a lot of the problems  I face at work. Not just in the day job, but in side projects as well. I&#8217;ve bitched about O/R-Ms before, but one of the biggest problems that users of O/R-Ms (developers) face is that the ideal way to model data for object-oriented programming bears no resemblance to the ideal way to store relational data. A recent article about <a href='http://gigaom.com/2010/06/08/how-zynga-survived-farmville/' target='_blank'>scaling Farmville</a> hints at this &#8211; the developers of Farmville managed scale by storing everything in a key-value store (memcached) before persisting to a relational data store later. Digg does <a href='http://about.digg.com/blog/looking-future-cassandra' target='_blank'>something</a> <a href='http://about.digg.com/node/564' target='_blank'>similar</a> with Cassandra. It&#8217;s not like these guys are idiots, the blog posts from Digg show that they know their stuff.</p>
<p>MongoDB lets me solve these problems. I can control the frequency of syncs to disk (just as I can in PostgreSQL) to improve raw write performance to memory. I only have to worry about storing data the way my application expects to see the data &#8211; arrays and hashes &#8211; without worrying about building many-to-many join tables. </p>
<p>What about DMVs and data integrity and a write-ahead log and indexes? MongoDB has <a href='http://www.mongodb.org/display/DOCS/Monitoring+and+Diagnostics' target='_blank'>instrumentation</a> and  <a href='http://www.mongodb.org/display/DOCS/Indexes' target='_blank'>indexes</a>. Yeah, you <a href='http://www.mongodb.org/display/DOCS/Durability+and+Repair' target='_blank'>sacrifice some durability</a> but many applications don&#8217;t need that. Hell, Amazon has even designed their systems to account for the <a href='http://www.infoq.com/news/2009/01/EventuallyConsistent,' target='_blank'>potential of failure</a>. </p>
<p>When I start my next application, I&#8217;m going to look long and hard at the platform I&#8217;m building on. There&#8217;s a good chance it&#8217;s not going to be a relational database and a really good chance it&#8217;s not going to be using SQL Server. It&#8217;s not because I have a problem with SQL Server or even RDBMSes, but because there are other choices that give me the flexibility I need to solve the problems I&#8217;m facing.</p>
<p>This is nothing against SQL Server 2008 R2, it&#8217;s a great step forward in the direction that SQL Server seems to be going. Sometimes I wonder if SQL Server and I are on the same road.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=eQK4xGvT8k0:JkJcW1jlJTU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=eQK4xGvT8k0:JkJcW1jlJTU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=eQK4xGvT8k0:JkJcW1jlJTU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=eQK4xGvT8k0:JkJcW1jlJTU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=eQK4xGvT8k0:JkJcW1jlJTU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=eQK4xGvT8k0:JkJcW1jlJTU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=eQK4xGvT8k0:JkJcW1jlJTU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=eQK4xGvT8k0:JkJcW1jlJTU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?i=eQK4xGvT8k0:JkJcW1jlJTU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/facility9_syndication?a=eQK4xGvT8k0:JkJcW1jlJTU:zYSYRoQSaQY"><img src="http://feeds.feedburner.com/~ff/facility9_syndication?d=zYSYRoQSaQY" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/facility9_syndication/~4/eQK4xGvT8k0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://facility9.com/2010/06/15/t-sql-tuesday-did-he-just-say-that-edition/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://facility9.com/2010/06/15/t-sql-tuesday-did-he-just-say-that-edition</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 8.874 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-07-29 09:05:20 --><!-- Compression = gzip -->
