Archive for the ‘SQL Server’ Category

Enabling Danish for SQL Server FullText

Monday, August 9th, 2010

SQL Server FullText enables you to search large amount of strings fast, and it is easy to use. It hasn’t changed much since SQL Server 2000.
A simple getting started tutorial can be found on Code Project.

SQL Server FullText is easy to use in applications requiring string searching.

The Danish, Polish and Turkish wordbreaker and stemmer implementations for SQL Server FullText is not developed by Microsoft and therefore not enabled by default. The libraries are however part of the installation process and are therefore present on disk.

To make use of the Danish language capabilities in SQL Server 2008, register the libraries in registry and reload the FullText languages:

  1. Download & run the DanishFulltext.reg file on the server. It will register wordbreaker, stemmer and default location of the thesaurus xml file.
  2. Run the exec sp_fulltext_service ‘update_languages’ in a Management Studio.

Now verify that Danish is enabled with this query: SELECT name FROM sys.fulltext_languages

Note: The DanishFullText.reg assumes that SQL Server is a default instance (not a named instance). If not, modify the file by changing the MSSQL10.MSSQLSERVER to the instance name.

It is the same case with Polish and Turkish – they are not registered by default. See more in the MSDN article How to: Load Licensed Third-Party Word Breakers.

List of out of the box SQL Server 2008 FullText supported languages: Arabic, Bengali (India), Brazilian, British English, Bulgarian, Catalan, Chinese (Hong Kong SAR, PRC), Chinese (Macau SAR), Chinese (Singapore), Croatian, Danish, Dutch, English, French, German, Gujarati, Hebrew, Hindi, Icelandic, Indonesian ,Italian, Japanese, Kannada, Korean, Latvian, Lithuanian, Malay – Malaysia, Malayalam, Marathi, Neutral, Norwegian (Bokmål), Polish, Portuguese, Punjabi, Romanian, Russian, Serbian (Cyrillic), Serbian (Latin), Simplified Chinese, Slovak, Slovenian, Spanish, Swedish, Tamil, Telugu, Thai, Traditional Chinese, Turkish, Ukrainian, Urdu, Vietnamese.

Meeting the SQL Azure Development Team

Wednesday, June 30th, 2010

Last week I was at Microsoft HQ in Redmond, WA, USA. I was invited by the SQL Azure Development Team to look at some of the new unreleased features and comment on features in their roadmap.

Unfortunately most of the content was confidential, meaning that I was under NDA, so I may not disclose any details. Sorry :-/

During the week with the SQL Azure Development Team I was fortunate to be engaged in technical detailed discussion about some of the upcoming feature releases – mainly discussing the SQL Server features not currently available in SQL Azure. It was interesting and enlightening at the same time to discuss their technical challenges and why they have build SQL Azure the way they have.

All in all, my conclusion after this event is that Microsoft takes SQL Azure seriously and it will become a major player in the RDBMS world. It will not just be a SQL Server in the cloud, but a separate product with different market segments and different features. I am looking forward to a bright future with SQL Azure :-)

Finding Missing Indexes with SQL Server DMVs

Monday, May 10th, 2010

Finding Missing Indexes with DMVsSome time ago I wrote written about easy index wins for SQL Server 2005.

SQL server maintains statistics about indexes you should consider creating. This time I’ll show you a DMV (Dynamic Management View) that lists index candidates. This method works for SQL Server 2005 SP2 and later versions.

The query is based on three DMVs and returns index candidates where the calculated improvement is more than 10%:

SELECT
  migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure_pct,
  QUOTENAME(db_name(mid.database_id)) AS [database],
  QUOTENAME(OBJECT_SCHEMA_NAME(mid.object_id, mid.database_id)) AS [schema],
  QUOTENAME(OBJECT_NAME(mid.object_id, mid.database_id)) AS [table],
  'CREATE INDEX [missing_index_' + CONVERT(varchar(64), NEWID()) + ']'
  + ' ON ' + mid.statement
  + ' (' + ISNULL (mid.equality_columns, '')
  + CASE
      WHEN mid.equality_columns IS NOT NULL
	    AND mid.inequality_columns IS NOT NULL THEN ','
      ELSE ''
    END
  + ISNULL(mid.inequality_columns, '')
  + ')'
  + ISNULL(' INCLUDE (' + mid.included_columns + ')', '')
	  AS create_index_statement,
  migs.*,
  mid.database_id,
  mid.[object_id]
FROM sys.dm_db_missing_index_groups mig
  INNER JOIN sys.dm_db_missing_index_group_stats migs
	ON migs.group_handle = mig.index_group_handle
  INNER JOIN sys.dm_db_missing_index_details mid
	ON mig.index_handle = mid.index_handle
WHERE
	migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) *
		(migs.user_seeks + migs.user_scans) > 10
ORDER BY
	migs.avg_total_user_cost * migs.avg_user_impact *
		(migs.user_seeks + migs.user_scans) DESC

It is important to note, that these are index candidates are only candidates and the improvements are based on estimates. The estimated improvement does not take extra disk space requirements and the maintenance of the indexes during updates, inserts and deletes. Furthermore it does not make recommendation about usage of clustered or non-clustered indexes.

This blog post is inspired by Bart Duncan’s Are you using SQL’s missing index DMVs?

Miracle Open World 2010 Lucene Presentation

Tuesday, April 20th, 2010

The conference is over and it was a great success. I meet a lot of new people and had lots of technical discussions about .Net, graph databases, freetext search, SQL Server, Oracle Service Bus, debugging with WinDbg and extensions.

The slides and demo code for my Lucene session is available here:

My session “Making freetext search with Lucene.Net work for you” abstract:

Lucene is an open source full-featured text search engine library, making searching in large amounts of text lightning fast. Lucene are in use by many large sites like Wikipedia, LinkedIn, MySpace etc.

It is easy to get started with Lucene, but there are many pitfalls… In this session you will learn about the do’s and don’t’s for indexing and searching, tools, scaling, new features in version 2.9 and some of the more advanced features.

This presentation will use the Microsoft .Net implementation of Lucene named Lucene.Net, but the content of this presentation applies for ported versions of Lucene.

Speaking about Lucene at Miracle Open World 2010

Sunday, April 4th, 2010

The conference Miracle Open World 2010 is soon upon us at Legoland (April 14.-16.) :-)

There will be four tracks this year: Oracle track, SQL Server track, .Net track and a workshop track.

The conference is legendary because time spend at the conference is divided between 80% technical stuff and 80% social networking. No kidding’ socializing is a big part of this conference with gala-dinner and the not-to-miss beach party at Lalandia Aquadome (including drinks).

This year I only have one session where I’ll be presenting Lucene.Net.

Session abstract:

Lucene is an open source full-featured text search engine library, making searching in large amounts of text lightning fast. Lucene are in use by many large sites like Wikipedia, LinkedIn, MySpace etc.

It is easy to get started with Lucene, but there are many pitfalls… In this session you will learn about the do’s and don’t’s for indexing and searching, tools, scaling, new features in version 2.9 and some of the more advanced features.

This presentation will use the Microsoft .Net implementation of Lucene named Lucene.Net, but the content of this presentation applies for ported versions of Lucene.

At the time of writing, 207 participants have registered for the conference. You can still register – it’s not too late.

See more at the Miracle Open World 2010 site.

SQL Server build version

Wednesday, March 17th, 2010


Working with SQL Server it is often important to know which edition, version and service pack applied to the instance.

This information easily retrieve with either of these two system functions ServerProperty or @@Version:

SELECT @@VERSION

SELECT SERVERPROPERTY('ProductVersion'),
       SERVERPROPERTY('ProductLevel'),
       SERVERPROPERTY('Edition')

Both of the returns roughly the same information, but I tend to use the @@Version function as it easier to remember and type.

With the ServerProperty function additional information can be retrieved like MachineName, InstanceName or BuildClrVersion. See more about the ServerProperty function on MSDN.

From the build number alone it is possible to figure out which version of the SQL Server and Service Packs applied via the below table:

RTM SP1 SP2 SP3 SP4
SQL Server 2008 R2 10.50.1600.1
SQL Server 2008 10.00.1600.22 10.00.2531
SQL Server 2005 9.00.1399.06 9.00.2047 9.00.3042 9.00.4035
SQL Server 2000 8.00.194 8.00.384 8.00.532 8.00.760 8.00.2039

Credit for the above table is due to this site.

Update April 30th 2010: Added SQL Server 2008 R2 RTM build number

Transferring SQL Server logins

Monday, March 1st, 2010

I had to migrate a SQL Server 2008 instance on to new hardware.

I choose to detach the databases and attach the databases on the new SQL Server 2008 instance on the new hardware. This was easy, but the origin SQL Server instance used mixed SQL Server and Windows Authentication Mode. This also meant that I had to migrate SQL Server logins, as the logins where a mix of SQL Server logins and Active Directory domain accounts/groups.

Both the SQL Server logins and domain accounts/groups has an unique SID (Security Identifier), which ties the logins in the SQL Server with the users in the database.

While the domain accounts/groups resides in the Active Directory domain controllers, the SQL Server logins only resides in the SQL Server. This means, moving domain accounts/groups is easy, by just creating the same users in the new SQL Server instance, but SQL Server logins is not. I could either choose to:

  • Recreate the SQL Server logins with new users in each of the databases, as new SQL Server logins will get new SIDs and therefore not be tied to the old database users. This also requires that you know all the passwords – alternative reconfigure all the client applications using SQL Server logins :-(
  • Transfer the SQL Server logins with SID and password :-)

How to transfer SQL Server logins? See the KB article: How to transfer the logins and the passwords between instances of SQL Server 2005 and SQL Server 2008. Easy :-)

Reuse in SQL Server 2008 Integration Services

Thursday, October 22nd, 2009

Or lack of :-(

My current project requires SSIS (SQL Server 2008 Integration Services) packages for ETL processing.

SSIS seems very capable, but lacks fundamental things that a developer like me takes for granted. I did not expect SSIS to have the ability of inheritance as it isn’t object-oriented, but I did expect functions or methods like a procedural language or set-based languages like T-SQL. Sadly the answer is no.

You can make script tasks or script component with custom T-SQL or .Net code, but logic in expressions you have to duplicate.

I goggled reuse and SSIS and found this statement in an article about reuse in SSIS at SqlServerCentral.com:

Let’s not forget, copy&paste is the first level of code reuse

In essence it’s true, but I would hope the entire Information Technology industry has move way beyond this point years ago.

This post at the Microsoft SQL Server forum confirms this horrific truth about lack of reuse in SSIS :-(

Change Data Capture (CDC) in SQL Server 2008

Tuesday, August 11th, 2009

I where planning to write a blog post about Change Data Capture (CDC) in SQL Server 2008, but then I stumbled upon Pinal Dave’s article Introduction to Change Data Capture (CDC) in SQL Server 2008.

It is a thorough overview of Change Data Capture (CDC).

MSDN reference for Change Data Capture (CDC).

Loooong running sql statement

Monday, April 6th, 2009

Sql Server Profiler renegate statement

I was using SQL Server Profiler on a SQL Server 2005 Enterprise Edition looking for performance culprits, when I stumbled upon this very long running process.

I think this must be a world record. :-)

This statement has only used 16 milliseconds of CPU but it has been running for more than 500.000 years!