<?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>Cymen&#039;s Blog &#187; Microsoft</title>
	<atom:link href="http://blog.cymen.org/category/microsoft/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.cymen.org</link>
	<description></description>
	<lastBuildDate>Fri, 03 Feb 2012 17:53:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>SQL Server &#8211; Ranking names for search results by position of query within name</title>
		<link>http://blog.cymen.org/2011/10/19/sql-server-ranking-names-for-search-results-by-position-of-search-within-name/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-ranking-names-for-search-results-by-position-of-search-within-name</link>
		<comments>http://blog.cymen.org/2011/10/19/sql-server-ranking-names-for-search-results-by-position-of-search-within-name/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 16:23:21 +0000</pubDate>
		<dc:creator>Cymen</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://blog.cymen.org/?p=235</guid>
		<description><![CDATA[SQL Server using PATINDEX() and LEFT() When searching names there are some assumptions we can make (based on first and last name being in separate columns): A match in the last name is more important than a match in the first name The position of the match within the last name is important: an earlier [...]]]></description>
			<content:encoded><![CDATA[<h2>SQL Server using PATINDEX() and LEFT()</h2>
<p>When searching names there are some assumptions we can make (based on first and last name being in separate columns):</p>
<ul>
<li>A match in the last name is more important than a match in the first name</li>
<li>The position of the match within the last name is important: an earlier match is a better match</li>
<li>The first name should still be search</li>
<li>If present, a middle name is least important</li>
</ul>
<p>It is possible to do this with SQL Server using the following proprietary extensions:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ms188395.aspx">PATINDEX(needle, haystack)</a>: returns position of needle within haystack and (unfortunately in our use case) 0 if not present.</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ms177601.aspx">LEFT(string, count)</a>: returns substring of string up to length of count (note: will truncate string if length greater than count!)</li>
</ul>
<pre class="brush: sql">SELECT TOP 10 firstName + ' ' + middleName + ' ' + lastName
FROM Member
WHERE [firstName] + ' ' + [middleName] + ' ' + [lastName] LIKE @query
ORDER BY
  PATINDEX (
    @query,
    LEFT([lastName] + '                                                                                          ', 90)
    + LEFT([firstName] + '                                                                                          ', 90)
    + [middleName]
  ),
  [lastName],
  [firstName],
  [middleName]
  -- Note: the ' .... ' above is a string of spaces of length 90</pre>
<p>We are making a big assumption: none of the name fields will have a length &gt; 90. You may need to adjust this value for your use case. The reason we need to do this is that PATINDEX() will return 0 if the value is not present so we can&#8217;t simply due a nice ORDERBY PATINDEX(@query, lastName), PATINDEX(@query, firstName), PATINDEX(@query, middleName). Instead, we have to concatenate the name fields into one long string but pad them so that variable length of the names will not affect the rank they are put in.</p>
<h2>MySQL using LOCATE() and LEFT()</h2>
<p>The same method should work in MySQL using the <a href="http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_locate">LOCATE()</a> and <a href="http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_left">LEFT()</a> functions. Both appear to be identical in usage to the SQL Server functions.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cymen.org/2011/10/19/sql-server-ranking-names-for-search-results-by-position-of-search-within-name/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Great SQL formatter</title>
		<link>http://blog.cymen.org/2011/03/30/great-sql-formatter/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=great-sql-formatter</link>
		<comments>http://blog.cymen.org/2011/03/30/great-sql-formatter/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 22:07:00 +0000</pubDate>
		<dc:creator>Cymen</dc:creator>
				<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Express]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.cymen.org/?p=183</guid>
		<description><![CDATA[The best SQL formatter I&#8217;ve found so far is: sqlformat.appspot.com It works nicely with subqueries which is becoming increasingly important for my use of it.]]></description>
			<content:encoded><![CDATA[<p>The best SQL formatter I&#8217;ve found so far is:<br />
<a href="http://sqlformat.appspot.com/">sqlformat.appspot.com</a><br />
It works nicely with subqueries which is becoming increasingly important for my use of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cymen.org/2011/03/30/great-sql-formatter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server Express and Performance Tuning</title>
		<link>http://blog.cymen.org/2010/08/18/sql-server-express-and-performance-tuning/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sql-server-express-and-performance-tuning</link>
		<comments>http://blog.cymen.org/2010/08/18/sql-server-express-and-performance-tuning/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 20:31:07 +0000</pubDate>
		<dc:creator>Cymen</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[SQL Server Express]]></category>

		<guid isPermaLink="false">http://blog.cymen.org/?p=165</guid>
		<description><![CDATA[One of the tricky things with SQL Server Express is that tools like the index tuning wizard and similar are not supported or available. A work around for the lack of the Microsoft profiler is the AnjLab Sql Profiler which does work with the 2005 and 2008 SQL Server Express products. Recently, I was faced [...]]]></description>
			<content:encoded><![CDATA[<p>One of the tricky things with SQL Server Express is that tools like the index tuning wizard and similar are not supported or available. A work around for the lack of the Microsoft profiler is the <a href="http://sites.google.com/site/sqlprofiler/">AnjLab Sql Profiler</a> which does work with the 2005 and 2008 SQL Server Express products.</p>
<p>Recently, I was faced with a database that needed a number of indexes to improve performance. The database was running on SQL Server Express 2008 R2 so I couldn&#8217;t be lazy and use the index tuning wizard. Some research revealed these resources:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/magazine/cc135978.aspx">Uncover Hidden Data to Optimize Application Performance</a></li>
<li><a href="http://blog.sqlauthority.com/2010/05/14/sql-server-find-most-expensive-queries-using-dmv/">Find Most Expensive Queries Using DMV</a></li>
</ul>
<p><strong>Quickly finding likely columns to index</strong></p>
<pre class="brush: sql">
SELECT TOP 10
[Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0)
, avg_user_impact
, TableName = statement
, [EqualityUsage] = equality_columns
, [InequalityUsage] = inequality_columns
, [Include Cloumns] = included_columns
FROM sys.dm_db_missing_index_groups g
INNER JOIN sys.dm_db_missing_index_group_stats s
ON s.group_handle = g.index_group_handle
INNER JOIN sys.dm_db_missing_index_details d
ON d.index_handle = g.index_handle
ORDER BY [Total Cost] DESC;
</pre>
<p>This is as simple as running the query above as found in the first referenced article. As one adds indexes, simply refresh the query and you&#8217;ll continue to see more items. Note that in some cases if views are in use the suggested indexes may be present but unused by the view. In that case, one should take a closer look at how views work and potentially alter the views to support indexing of the view columns.</p>
<p><strong>Finding likely columns to index via heavy queries</strong></p>
<pre class="brush: sql">
SELECT TOP 10 SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.TEXT)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.total_logical_writes, qs.last_logical_writes,
qs.total_worker_time,
qs.last_worker_time,
qs.total_elapsed_time/1000000 total_elapsed_time_in_S,
qs.last_elapsed_time/1000000 last_elapsed_time_in_S,
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.total_logical_reads DESC -- logical reads
-- ORDER BY qs.total_logical_writes DESC -- logical writes
-- ORDER BY qs.total_worker_time DESC -- CPU time
</pre>
<p>The other way to approach index creation is to look at the heavier queries and see what they are doing. The query above comes from the second referenced article. In some cases, it is obvious that indexes will help. Looking at the actual queries being run is a lot of help because sometimes it is clear that the problem is with query itself. In that case, either the query needs to be modified or the approach to getting that information needs to be rethought (an example of that would be moving to a nightly batch process to collate expensive-to-query data).</p>
<p>In both cases one has to be critical of the work being done. Index creation is a bit of an art because simply indexing everything is not an option. Thinking about joins and indexes when designing the database is definitely helpful but going back to add them can be done and it doesn&#8217;t have to be painful even when using SQL Server Express!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cymen.org/2010/08/18/sql-server-express-and-performance-tuning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abit Airpace and Windows Server 2008 64bit</title>
		<link>http://blog.cymen.org/2008/11/26/abit-airpace-and-windows-server-2008-64bit/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=abit-airpace-and-windows-server-2008-64bit</link>
		<comments>http://blog.cymen.org/2008/11/26/abit-airpace-and-windows-server-2008-64bit/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 06:49:36 +0000</pubDate>
		<dc:creator>Cymen</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[abit airpace]]></category>
		<category><![CDATA[drivers]]></category>
		<category><![CDATA[server 2008]]></category>
		<category><![CDATA[vista]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://blog.cymen.org/?p=30</guid>
		<description><![CDATA[To get the Abit Airpace wi-fi card to work with Windows Server 2008 64bit grab the generic Atheros drivers from with a file name similar to vista-7.6.0.126-whql.zip: http://www.atheros.cz/ Then edit one of the two .inf files depending on: 32bit: netathr.inf 64bit: netathrx.inf And add these two lines under [Atheros.NTX86] (or 64bit: [Atheros.NTamd64]): ; Abit Airpace [...]]]></description>
			<content:encoded><![CDATA[<p>To get the Abit Airpace wi-fi card to work with Windows Server 2008 64bit grab the generic Atheros drivers from with a file name similar to <strong>vista-7.6.0.126-whql.zip</strong>:</p>
<p><a href="http://www.atheros.cz/" target="_blank">http://www.atheros.cz/</a></p>
<p>Then edit one of the two .inf files depending on:</p>
<p>32bit: netathr.inf<br />
64bit: netathrx.inf</p>
<p>And add these two lines under [Atheros.NTX86] (or 64bit: [Atheros.NTamd64]):</p>
<p>; Abit Airpace<br />
%ATHR.DeviceDesc.3067%              = ATHR_DEV_001C.ndi,        PCI\VEN_168C&amp;DEV=001C&amp;SUBSYS_1033147B</p>
<p>Now reinstall the driver using the folder with the modified .inf file as the driver source. Note that these instructions will work for Windows Server 2008 32bit, Server 2008 64bit, Vista 32bit and Vista 64bit.</p>
<p><a href="http://blog.cymen.org/wp-content/uploads/2008/11/vista-760126-whql-airpace.zip">vista-760126-whql-airpace</a> (locally-hosted modified version to support Abit Airpace)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cymen.org/2008/11/26/abit-airpace-and-windows-server-2008-64bit/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

