Блог О пользователеscherbinin

Регистрация

Календарь

« Август 2011  
Пн Вт Ср Чт Пт Сб Вс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

Microsoft SQL Server и все, что с ним связано

 
 

Не очень известный факт о кластерном индексе


Казалось бы все уже давно разжевано, однако об одном интересном факте мало кто знает -- 
если кластерный индекс уникальный, то при создании неуникальных некластерных индексов, 
ключ кластерного индекса будет не только на листовом уровне дерева, но и в промежуточных узлах.

Об этом подробно написала Kalen Delaney в своем блоге:
http://sqlblog.com/blogs/kalen_delaney/archive/2010/03/07/more-about-nonclustered-index-keys.aspx

Не пересказывая г-жу Дилани, отмечу только, что это приводит к интересному эффекту -- 
при наличии уникального кластерного индекса по полю X и неуникального некластерного 
индекса по полю Y, для запроса вида 
select ... where Y = @param1 and X = @param2 
при использовании некластерного индекса, index seek будет по обоим полям -- Y, X, а не только по Y.
Если же этот индекс сделать уникальным, то, как и ожидается, ключ кластерного индекса будет только 
на листовом уровне, и index seek будет только по Y.

 

SSAS parallel transactional incremental partitions processing


Dealing with huge amounts of data and SSAS? Have you ever tried parallel transactional incremental partitions processing? Odd enough but in this typical (at least to me and my team) scenario AMO generates invalid XMLA-script (because in this case all < Bindings > tags must be outside of the < Process > tag). As a result, you will get an exception.

 However, it is easy to fix – let’s move all < Bindings > out of the < Process > command (I know, this code is far from perfect, feel free to refactor):

static string FixXMLAForParallel(string log, string SSASDatabaseName, string SSASDatabaseId, string DWHConnString)

        {

            string bindings = "< Bindings >";

 

            while (log.Contains("< Bindings >"))

            {

                int bindingsOpen = log.IndexOf("< Bindings >");

                int bindingsClose = log.IndexOf("< /Bindings >");

 

                int bindOpen = log.IndexOf("< Binding >", bindingsOpen + "< Bindings >".Length);

                int bindClose = log.IndexOf("< /Binding >");

 

                bindings += log.Substring(bindOpen, bindClose - bindOpen + "< /Bindings >".Length);

 

                log = log.Remove(bindingsOpen, bindingsClose - bindingsOpen + "< Bindings >".Length + 1);

            }

 

            bindings += "< /Bindings >";

            bindings += (@"< DataSource xmlns:xsd=""http://www.w3.org/2001/XMLSchema";" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance";" xsi:type=""RelationalDataSource"" >" +

                "< ID >" + SSASDatabaseId + "< /ID >" +

                "< Name >" + SSASDatabaseName + "< /Name >" +

                "< ConnectionString >" + DWHConnString + "< /ConnectionString >" +

                "< ConnectionStringSecurity >Unchanged< /ConnectionStringSecurity >" +

                "< /DataSource >");

 

            log = log.Insert(log.IndexOf("< /Parallel >") + "< /Parallel >".Length, bindings);

            return log;

        }

 

And a usage example:

srv.CaptureXml = true;

ProcessDCPartitions(...);

srv.CaptureXml = false;

log = srv.ConcatenateCaptureLog(true, true);

results = srv.Execute(FixXMLAForParallel(log));

CheckProcessingError(results);

srv.CaptureLog.Clear();

 

private void CheckProcessingError(XmlaResultCollection results)

{

string error = "";

 

foreach (XmlaResult result in results)

{

foreach (XmlaMessage message in result.Messages)

                {

                    if (message is XmlaError)

                    {

                        error = error + message.Description + "\n";

                    }

                }

}

 

if (!string.IsNullOrEmpty(error))

{

                throw new Exception(error);

}

 

}

 


 
Теги: ssas processing