.NET 4.5: INotifyPropertyChanged vereinfacht 28.03.2012

Matthias Jauernig
Matthias Jauernig, Senior eXpert

Innerhalb einer Methode herauszufinden, von wo man eigentlich aufgerufen wurde, war unter .NET bisher nur unter Umständen möglich, z.B. mit der StackTrace-Klasse. Dabei ist es für viele Anwendungsszenarien sinnvoll, schnell und möglichst automatisch den direkten Aufrufer zu kennen, z.B. zur Implementierung von INotifyPropertyChanged. Mit .NET 4.5 und den Compiler Services ist das im Handumdrehen erledigt.

Manchmal sind es die kleinen Dinge, die man in einer neuen .NET-Framework-Version entdeckt und die einen entzücken. In Silverlight und auch WPF gibt es schon immer das INotifyPropertyChanged-Interface, über das eine Klasse Änderungen an ihren Properties bekanntmachen kann, sodass sich die UI automatisch aktualisiert. Allerdings muss der Entwickler dabei den Namen des Properties als String übergeben, was sowohl aufwendig als auch fehleranfällig ist. Konkret hat das bisher z.B. so ausgesehen:

   1: public class ProductsViewModel : INotifyPropertyChanged
   2: {
   3:     private decimal _priceTotal;
   4:     public decimal PriceTotal
   5:     {
   6:         get { return _priceTotal; }
   7:         set
   8:         {
   9:             _priceTotal = value;
  10:             NotifyPropertyChanged("PriceTotal");
  11:         }
  12:     }
  13:  
  14:     public void NotifyPropertyChanged(string propertyName)
  15:     {
  16:         if (PropertyChanged != null)
  17:         {
  18:             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  19:         }
  20:     }
  21:  
  22:     public event PropertyChangedEventHandler PropertyChanged;
  23: }

Das ist fehleranfällig gegenüber Schreibfehlern und problematisch bei Refactoring-Aufgaben, die Wartbarkeit leidet darunter. Zwar kann man sich auch seine eigene Hilfsfunktionalität schreiben, mit der man den Propertynamen als Lambda Expression übergibt und aus dem dann der Name als String per Analyse des Expression Trees extrahiert wird. Doch auch hier gibt es Nachteile, z.B. in der komplizierten und zeitaufwendigen Auswertung der Lambda Expression per Reflection. Ein Delegate zu verwenden nur um einen Propertynamen zu übergeben kann zudem für einige Entwickler verwirrend sein.

.NET 4.5 stellt der manuellen String-Übergabe ein alternatives Konzept gegenüber. Es liefert mit den neuen Compiler Services drei sogenannte Caller Information-Attribute, durch die eine Methode Informationen über den Aufrufer auslesen kann. Wichtig dabei: Nicht der Entwickler, sondern der Compiler stellt Informationen über den Aufrufer bereit! Bei den neuen Attributen handelt es sich um:

  • CallerFilePath: Liefert den vollen Pfad der Sourcedatei des Aufrufers (zur Compilezeit).
  • CallerLineNumber: Liefert die Zeilennummer des Aufrufs in der Sourcedatei des Aufrufers.
  • CallerMemberName: Liefert den Methoden- oder Property-Namen des Aufrufers.

Für unsere Zwecke von INotifyPropertyChanged ist vor allem das letzte Attribut interessant. Nutzen lässt es sich wie folgt:

   1: public class ProductsViewModel : INotifyPropertyChanged
   2: {
   3:     private decimal _priceTotal;
   4:     public decimal PriceTotal
   5:     {
   6:         get { return _priceTotal; }
   7:         set
   8:         {
   9:             _priceTotal = value;
  10:             NotifyPropertyChanged();
  11:         }
  12:     }
  13:  
  14:     public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
  15:     {
  16:         if (PropertyChanged != null)
  17:         {
  18:             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  19:         }
  20:     }
  21:  
  22:     public event PropertyChangedEventHandler PropertyChanged;
  23: }

Die Änderung im Code ist klein, aber entscheidend: Bei einem Aufruf von NotifyPropertyChanged() muss der Propertyname nicht mehr vom Entwickler mitgegeben werden. Stattdessen wird er durch Verwendung des CallerMemberName-Attributes vom Compiler automatisch in die NotifyPropertyChanged()-Methode injiziert und kann dann im Methodenrumpf verwendet werden. Interessant ist auch zu sehen, dass der propertyName-Parameter mit einem Default-Argument implementiert ist. Somit kann er bei Bedarf durch explizites Übergeben eines Wertes überschrieben werden, wenn dies notwendig ist (z.B. weil sich der Wert eines berechneten Properties durch Setzen eines anderen Properties ändert und sich die UI trotzdem entsprechend aktualisieren soll).

Diese Funktionalität macht natürlich nicht nur bei INotifyPropertyChanged Sinn. Auch beim Logging kann das einiges an fehlerträchtiger Programmierarbeit sparen und die Wartbarkeit steigt. Weitere Informationen finden sich u.a. in der MSDN-Doku zu INotifyPropertyChanged und in diesem guten Blogbeitrag.

Share |

Stabilere SSIS Entwicklung durch die neue T-SQL Funktion WITH RESULT SETS 26.03.2012

Thorsten Fleckenstein
Thorsten Fleckenstein, BI Principal eXpert
Aufbauend auf der Serie „Neue Funktionen im SQL Server 2012“ meines Kollegen Markus Schwamberger möchte ich in diesem Artikel auf eine weitere neue Funktion des SQL Servers 2012 hinweisen, die speziell für SSIS Entwickler sehr interessant sein könnte.

Jeder SSIS Entwickler kennt bestimmt die Problematik, dass man in seinen SSIS Paketen Abfragen oder Views auf eine Datenbanktabelle erstellt hat und aus irgendeinem Grund müssen in den zugrunde liegenden Tabellen Spaltennamen bzw. Datentypen geändert werden. Dies hat zur Folge, dass die SSIS Pakte nicht mehr lauffähig sind und angepasst werden müssen. Hier kommt die neue SQL Server 2012 Funktion WITH RESULT SETS ins Spiel, die dieses Problem elegant löst.

Lassen sie uns jetzt zu einem Beispiel gehen, das die neue Funktion näher beleuchtet. Nach dem Ausführen des Skriptes erhalten Sie eine Tabelle mit mehreren Spalten und eine Stored-Procedure, die eine einfache Select-Abfrage auf die zuvor angelegte Tabelle ausführt.

USE tempdb
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Person]') AND type in (N'U'))
DROP TABLE [dbo].[Person]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Person](
    [ID] [int] NOT NULL,
    [PersonType] [nchar](15) NOT NULL,
    [FirstName] [nvarchar](50) NOT NULL,
    [LastName] [nvarchar](50) NOT NULL,
    [Activ] [bit] NOT NULL,
    [EntryDate] [datetime] NOT NULL,
 CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT INTO [dbo].[Person] VALUES (1,'Employee','Thorsten', 'Fleckenstein', 1, '20120201')
GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DemonstrateWithResultSetsFeatureOfDenali]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[DemonstrateWithResultSetsFeatureOfDenali]
GO

CREATE PROCEDURE DemonstrateWithResultSetsFeatureOfDenali
AS
BEGIN
 SELECT
  ID, 
  FirstName + ' ' + LastName AS FullName, 
  PersonType,
  Activ,
  EntryDate
 FROM dbo.Person
END
GO
GO

Führt man nun die Stored-Procedure in der gewohnten Art und Weise aus:
USE tempdb
GO
EXEC DemonstrateWithResultSetsFeatureOfDenali
GO
erhält man exakt die Spaltennamen und Datentypen, die vorher in der Tabelle definiert sind als Rückgabewerte der Select – Abfrage.



Ändert sich dabei der Datentyp in der Tabelle verändert sich dementsprechend auch der Datentyp der Stored-Procedure-Ausgabe, was wiederum zur Folge hätte, dass ein SSIS Paket welches diese Stored - Procedure als Datenquelle verwendet, nicht mehr funktionsfähig wäre. Führt man nun die gleiche Stored-Procedure mit dem neuen WITH RESULT SETS Feature von SQL Server 2012 aus, vermeidet man das oben beschriebene Problem.

EXEC DemonstrateWithResultSetsFeatureOfDenali 
WITH RESULT SETS
(
 ( 
  ID INT,
  ContactPersonName VARCHAR(150),
  PersonType VARCHAR(15),
  Activ SMALLINT,
  EntryDate DATE
 ) 
) 
Wie man im obigen Beispiel sehen kann, wird mit Hilfe der neuen WITH RESULT SETS Funktion exakt definiert, wie die Stored-Procedure die Daten zurückgeben soll. Im Beispiel wird der Name von FullName auf ContactPerson, sowie die Datentypen der Felder Activ und EntryDate geändert.



Vergleicht man die Ausgabe des ersten Beispiels mit der Ausgabe, die mit Hilfe der  WITH RESULT SETS Funktion erzeugt wird, kann man erkennen wie sich der Feldname und die Datentypen verändert haben. Ändert man nun Felder auf Tabellenebene, gibt die Stored - Procedure nach wie vor, die in der  WITH RESULT SETS Funktion definierten Werte zurück und ein SSIS Paket, welches diese Funktion als Datenquelle benutzt, würde keine Fehler verursachen.

Wie man sieht kann man mit Hilfe der neuen SQL Server 2012 WITH RESULT SETS Funktion eine erhebliche Verbesserung in der Wartung und Fehlersicherheit von SSIS – Paketen erzielen.Sicherlich bietet diese neuen Funktion auch viele weitere Einsatzmöglichkeiten in Entwicklungsprojekten.
Share |

Neues Pluralsight-Video: HTML5 und KnockoutJS 21.03.2012

Matthias Jauernig
Matthias Jauernig, Senior eXpert

Wie mit der JavaScript-Bibliothek KnockoutJS interaktive Web-Anwendungen auf Basis des aus Silverlight/WPF bekannten MVVM-Patterns geschrieben werden können, habe ich bereits in der dotnetpro Ausgabe 11/2011 beschrieben.

Insgesamt habe ich den Eindruck, dass KnockoutJS in realen Projekten immer stärkeren Anklang findet. Die Vorteile von deklarativen Daten-Bindings und automatischen View-Updates bei Datenänderungen scheinen viele Entwickler zu überzeugen.

Auf der Trainings-Webseite Pluralsight gibt es für registrierte Kunden seit ein paar Tagen den Kurs Building HTML5 and JavaScript Apps with MVVM and Knockout von John Papa, der sich eingehend mit KnockoutJS beschäftigt.

knockoutjs_logo

Share |

Der Blinde Fleck in C++: Garbage Collection 19.03.2012

Alexander Jung
Alexander Jung, Chief eXpert

"C++ is the best language for garbage collection principally because it creates less garbage." — Bjarne Stroustrup

Ein Zitat dem man immer wieder begegnet, und das gerne als Beleg für die Effizienz von C++ gegenüber .NET herangezogen wird – gerne auch als versteckter Seitenhieb, wie ich gerade wieder erfahren musste. (Ein immerhin rhetorisch sehr geschicktes Beispiel auch hier ab 30:50.)

Ich finde das immer etwas ärgerlich. Zum einen hat C++ solche Seitenhiebe nicht nötig, zum anderen ist die Schlussfolgerung leider so falsch wie die Aussage an sich richtig ist.

cpp C++ hat gemeinhin den Ruf schnelleren und effizienteren Code zu produzieren, als C# (wobei hier in der Regel MSIL gemeint ist), Java oder andere Sprachen. Prinzipiell ist das schon richtig, und zwar aus verschiedenen Gründen: Keine Laufzeitumgebung, die sich zwischen Anwendung und Betriebssystem klemmt; kein JIT-Compiler, der der Programmstart verzögert; keine Garbage Collection die… ja, was eigentlich?

Bei der Garbage Collection (GC) geht es zuerst und vor allem um die Freigabe von Speicher.

Hier höre ich schon die ersten Widersprüche: Was ist mit unmanaged Ressourcen? Datenbank connections, File handles, etc.? Genau die werden in .NET nicht über die GC entsorgt, sondern über das Dispose-Pattern – ebenso deterministisch wie unter C++. Der Finalizer ist hier nur ein zusätzliches Sicherheitsnetz.

In C++ gibt man Speicher auf dem Heap direkt über delete über Destruktoren frei, etwa in Smartpointer-Klassen. Der Code hat das unmittelbare Wissen um die Ressource, kann sie also auch ohne zusätzlichen Verwaltungsaufwand entsorgen. Eine GC hat im Vergleich dazu nicht nur die eigentliche Speicherfreigabe zu bewältigen, sondern muss darüber hinaus zunächst mühsam die Ressourcen zusammensuchen. Dazu kommt, dass noch nicht freigegebener Speicher “zusammengeschoben”, also mühsam kopiert werden muss.

Dass davon abgesehen die GC zu einem undefinierten Zeitpunkt losläuft und dann womöglich – zumindest potentiel – kurzzeitig die eigentliche Programmausführung anhält, ist ein Kontrollverlust, der einem C++-Entwickler sauer aufstößt. Bei Licht betrachtet ist es aber nur eine Verschiebung der Arbeit, die der Destruktor sofort ausführt.

So gesehen ist das Zitat und die Schlussfolgerung völlig korrekt: Wer gleich aufräumt hat in Summe weniger Arbeit.

Aber!

Garbage Collection ist hier gar nicht das Thema. Das Thema ist Speicherverwaltung bzw. Management und die Freigabe von Speicher ist hier nur ein Teilausschnitt. Der andere Aspekt ist das Anfordern von Speicher, und hier kippt die Bilanz dann wieder zugunsten von .NET (wobei zu beachten ist, dass das nicht pauschal für jede GC-Implementierung gilt, sondern für die in .NET umgesetzte Strategie).

Zunächst einmal geht .NET davon aus, dass der Heap bis zu einem bestimmten Punkt gefüllt und ab diesem Punkt frei ist. Eine Speicheranforderung reduziert sich dann in der Regel darauf, den Zeiger, der diesen Punkt markiert, um den Umfang des angeforderten Speichers zu verschieben. Was könnte effizienter sein?

Verglichen damit muss ein C++ heap manager damit zurechtkommen, dass Speicheranforderungen und Freigaben ungeordnet auftreten, und so über die Zeit der Speicherplatz auf dem Heap fragmentiert wird. Das erfordert den entsprechenden Aufwand um die genutzten und freien Abschnitte zu verwalten, um benachbarte Blöcke zusammenzufassen und bei Speicheranforderungen eine möglichst optimale Auswahl eines freien Blockes zu gewährleisten. Dieser Aufwand kommt nicht zum Null-Tarif.

Es gibt einen Grund, warum hochgezüchtete heap manager wie SmartHeap oder heap++ eine Auswirkung auf die Performance einer Anwendung haben.

Im Bezug auf Performance und Effizienz geht der Punkt Speicherallokation also ganz klar an .NET.

Neben diesem Effekt kann der .NET Garbage Collector aufgrund des gewählten Algorithmus weitere Vorteile für sich verbuchen: Das Zusammenschieben des noch verwendeten Speichers mag zunächst Arbeit sein, es führt aber zu höherer Lokalität der Zugriffe. Das heißt daß zumindest potentiell weniger Speicher commited werden muss, weniger Page faults auftreten und Prozessor Caches besser genutzt werden. Diese Effekte und weitere Optimierungen in der Implementierung der GC (Generationen, Large Object Heap) basieren aber auf statistischen Erwägungen – sie können zu Buche schlagen, aber ob und in welchem Maße ist im Einzelfall kaum vorhersehbar.

In Summe stehen sich also die Verfahren in C++ – geprägt von Determinismus – und in .NET – geprägt von statistischen Erwägungen – wie Hase und Igel gegenüber. Wobei sie allerdings im Laufe der Zeit ihre Rolle wechseln. Welches Verfahren im konkreten Einzelfall effizienter ist wird viel stärker von den spezifischen Eigenschaften einer Anwendung abhängen (und der Fähigkeit des Entwicklers mit und nicht gegen die Strategie zu arbeiten), als von der Frage Garbage Collection oder nicht.

C++ Code ist in vielen Aspekten effizienter als managed code: Dedizierte Kontrolle über das Speicherlayout ermöglicht effizientere Nutzung von Prozessor Caches; was über Templates typsicher als Iteration formuliert werden kann reduziert der Compiler auf simple Pointer-Inkrements ohne Bereichsprüfung bei jedem Zugriff; der Compiler kann deutlich besser optimieren, als ein JIT-Compiler; neue Möglichkeiten zur Optimierung werden traditionell zunächst in C++-Compilern umgesetzt; … .

Nur: Die Garbage Collection hat in dieser Liste nichts zu suchen.

Anhang: Weitere Informationen zu Garbage Collection…

Die GC in .NET basiert auf einem “mark and compact” Ansatz, kombiniert mit Generationen und einer Sonderbehandlung für große Speicherblöcke (Large Object Heap, LOH). Außerdem gibt es eine Workstation- und eine Server-Variante der GC.

Details dazu im MSDN Magazine:

Share |

Statistics in SQL Server 16.03.2012

Daniel Tonagel
Daniel Tonagel, Chief eXpert

Der Microsoft SQL Server benutzt Statistiken über Indices und Spalten, um die gestellten Abfragen zu optimieren. Dieser Artikel gibt einen Überblick der wesentlichen Optionen und Mechanismen in SQL Server 2005 und 2008 (incl. R2).

Wozu Statistiken?

Es genügt schon, eine ganz simple Abfrage zu betrachten:

SELECT * FROM Kunden WHERE Familienname BETWEEN 'M' AND 'SZZZ'

Gibt es keinen Index, kann man hier wenig optimieren, aber angenommen, es gäbe einen (nonclustered) Index auf Familienname. Sollen wir ihn benutzen oder nicht? Benutzen wir ihn nicht, müssen wir sämtliche Daten der Tabelle lesen und filtern. Benutzen wir ihn, können wir nur den relevanten Teil selektieren, müssen aber wegen des "SELECT *" für jeden Datensatz einen teuren Key-Lookup durchführen. Sollten wir die gewählte Query dann parallel auf mehreren Prozessoren durchführen, oder ist ein einzelner Thread sinnvoller?

Es ist leicht ersichtlich, dass die Beantwortung dieser Fragen im Wesentlichen von der Anzahl der Datensätze in der Tabelle, ihrer durchschnittlichen Größe und von der Verteilung der Namen abhängt. Genau aus diesem Grund benötigt der Query-Optimizer Statistiken. Statistiken werden per Default für jeden Index angelegt, sowie für Spalten, die zwar in keinem Index, aber in WHERE-Bedingungen auftauchen.

Datenbank Optionen

Das automatische Anlegen solcher Statistiken wird über die Datenbankoption AUTO_CREATE_STATISTICS kontrolliert. Diese ist standardmäßig eingeschaltet und es gibt angesichts des geringen Speicherbedarfs von Statistiken und ihrer essentiellen Wichtigkeit für den Query-Analyzer normalerweise keinen Grund, diese Option auszuschalten.

Eine weitere per Default eingeschaltete Option ist AUTO_UPDATE_STATISTICS. Eine veraltete Statistik kann schlimmer sein als gar keine, deshalb sollten die Statistiken möglichst up-to-date sein. Mit der Auto-Update Option markiert der SQL Server eine Statistik als veraltet, sobald sich ca. 20% der Daten in der betroffenen Spalte geändert haben. Die Statistik wird jedoch erst neu berechnet, wenn sie benötigt wird, also bei der nächsten Abfrage auf diese Spalte.

Schließlich gibt es noch die Option AUTO_UPDATE_STATISTICS_ASYNC. Das im letzten Absatz beschriebene Neuberechnen der Statistiken kann eine Weile dauern und verzögert damit die Ausführung der Query. Besonders bei großen Tabellen kann das zu unerwünschten Response-Zeiten oder sogar zu Timeouts führen. Dieses Verhalten lässt sich übrigens schwer reproduzieren, denn bei der nächsten Query ist wieder alles wie zuvor. Hier hilft ggf. ein Blick auf den letzten Updatezeitpunkt der Statistik via select object_name(object_id), stats_date(object_id, stats_id), * from sys.stats. Setzt man die Async Option, blockiert die Query nicht. Allerdings arbeiten dann die Querys mit den veralteten Statistiken bis das Update fertig ist.

Das automatische Statistik Update lässt sich pro Tabelle/Index/Statistik über die jeweilige NORECOMPUTE Option abschalten, falls AUTO_UPDATE_STATISTICS für die Datenbank eingeschaltet ist. Umgekehrt kann man jedoch nicht AUTO_UPDATE_STATISTICS abschalten und für individuelle Objekte anstellen. Stattdessen muss man dann alle Statistiken selbst pflegen.

Einen schnellen Überblick über die gesetzten DB Optionen verschafft
select * from sys.databases

Update Strategien

Wann macht es Sinn, Statistiken "von Hand" zu pflegen? Zum Beispiel, wenn man sehr große Tabellen in der Datenbank hat. Ein Statistik-Update kann hier durchaus mehrere Minuten dauern, deshalb sollte man dies lieber präventiv durchführen, z.B. im Rahmen eines nächtlichen Maintenance Tasks.

Verschärft wird das Problem noch bei Tabellen, denen ständig neue Daten hinzugefügt werden. Schlimmstenfalls werden nämlich genau diese neuen Daten ständig abgefragt. Da sie aber noch gar nicht in der Statistik erfasst sind, liefert der Query Optimizer ständig nicht optimale Query Pläne, was bei großen Tabellen dramatische Performanceauswirkungen haben kann. Werden die Daten batchweise hinzugefügt, bietet es sich an, am Ende des Batches noch ein manuelles Statistik-Update anzuhängen.

Bei solchen selbst ausgeführten Updates stellt sich noch die Frage nach der Samplegröße. Man kann einen vollständigen Scan ausführen (FULLSCAN), oder nur eine bestimmte Anzahl zufällig ausgewählter Werte einbeziehen ("SAMPLE 10 PERCENT" bzw. "SAMPLE 10000 ROWS"). In letzterem Fall braucht man abhängig von der Anzahl verschiedener Werte in der Spalte ein wenig Mathematik, um zu der korrekten Samplegröße zu kommen. Als Lackmustest kann man sich für einige einfache Querys den Actual Execution Plan anschauen und die vorhergesagte Zahl der Rückgabewerte mit den tatsächlichen vergleichen. Zumindest die Größenordnung sollte hier stimmen.

Fazit

Die Statistiken in SQL Datenbanken haben einen erheblichen Einfluss auf die Performance, nicht nur bei SELECT, sondern auch bei UPDATE und DELETE. Die Default-Einstellungen des Servers sind im allgemeinen Fall ausreichend, stoßen aber speziell bei großen Datenbanken auch an ihre Grenzen. Die Statistiken sollten daher gut verstanden sein, beobachtet und intelligent gepflegt werden.

Quellen
http://www.sqlskills.com/BLOGS/KIMBERLY/category/Statistics.aspx
http://msdn.microsoft.com/en-us/library/dd535534.aspx
http://www.sqlservercentral.com/blogs/steve_jones/2009/10/28/how-many-rows-have-changed/
Share |

Gewinnübergabe im SDX Office 15.03.2012

Svenja Henß
Svenja Henß, Senior Assistant

Gestern Abend war es endlich soweit:

Der Gewinner unseres Fotowettbewerbs vom SQL Server 2012 Launch in Köln, konnte sein neues Nokia Lumia 800 im SDX Office abholen.

Wir wünschen ihm ganz viel Spaß damit!

Nokia Gewinner

 

Alle eingesendeten Bilder gibt es >hier<

Share |

Serverseitiges Paging im SQL Server 2012 14.03.2012

Markus Schwamberger
Markus Schwamberger, Senior eXpert

Eine öfters vermisste Funktion im SQL Server ist das Paging. Die Möglichkeit die Anzahl der gelieferten Datensätze einzuschränken, wenn nur ein Teilbereich der Daten auf einer Seite dargestellt werden soll.

Mit der neuen Version SQL Server 2012 hat Microsoft diesen Wunsch endlich erhört und erweitert ORDER BY um die neuen Befehle OFFSET und FETCH.

OFFSET gibt den Startpunkt der Abfrage an und FETCH die Anzahl der der Datensätze. Beide Befehle können nur in Kombination mit ORDER BY verwendet werden.

Hier ein kleines Beispiel:

SELECT [FirstName], [LastName]
FROM [Person].[Contact]
ORDER BY [LastName]
OFFSET 100 ROWS -- Überspringe die ersten 100 Datensätze
FETCH NEXT 50 ROWS ONLY; -- Liefere 50 Datensätze

Somit ist es nun auch mit dem SQL Server möglich einfach und ressourcenschonend ein Paging umzusetzen.

Mehr Informationen und Beispiele in der MSDN:

http://msdn.microsoft.com/en-us/library/ms188385%28v=SQL.110%29.aspx#Offset

Share |

Windows Phone kommt langsam an... 12.03.2012

Matthias Jauernig
Matthias Jauernig, Senior eXpert

Dass Microsoft mit Windows Phone einen langen Atem brauchen würde, um gegen Android-Smartphones und das iPhone bestehen zu können, war von Anfang an klar. Und so war es nicht verwunderlich, das die Verkaufszahlen von Windows Phone 7 in 2011, gerade in den USA, alles andere als rosig aussahen.

Doch neueste Zahlen geben Grund zu vorsichtiger Zuversicht… Mango und Nokia sei Dank!

Microsoft’s Marktanteil sinkt

Der Anteil von Microsoft am Smartphone-Markt ist laut Gartner im Jahresvergleich von Q4/2010 zu Q4/2011 von 3,4% auf 1,9% gefallen. Die Anzahl der verkauften Einheiten ging von 3,419 Mio. auf 2,759 Mio. Stück zurück.

windows_phone_logoDas scheint zunächst im Widerspruch zum Titel dieses Beitrags zu stehen, tut es aber nicht! Denn Gartner unterscheidet bei seiner Statistik nicht zwischen Windows Phone und Windows Mobile und in Q4/2010 wurden noch viele alte Windows-Mobile-Geräte verkauft, dagegen schätzungsweise aber nur 0,5 Mio. Windows Phone Geräte. In Q4/2011 geht Gartner davon aus, dass nur noch Windows-Phone-Geräte verkauft wurden.

Microsoft muss also zunächst einmal das Tal des Marktanteils durch das gefallene Interesse an Windows Mobile hinter sich lassen, bevor die nackten Zahlen von Windows Phone Wirkung zeigen können. Daher sieht es im Jahresvergleich insgesamt schlecht für Microsoft aus, doch betrachtet man nur Windows Phone, ergibt sich ein anderes Bild.

Tendenz langsam steigend…

Lässt man Windows Mobile außen vor, so konnte Windows Phone seinen Marktanteil bei verkauften Smartphones im Vergleich von Q4/2010 zu Q4/2011 von 0,49% auf 1,85% um ca. 450% steigern! Doch von null kommend sagt solch ein großer Prozentsatz nichts aus. Doch wie stellt sich das hingegen in einem aktuelleren Zeitraum dar? Nachfolgend sind die Zahlen von Q3/2011 und Q4/2011 aufgezeigt (Gartner: Q3, Q4):

Q3/2011:

  • Verkaufte Smartphones: 115,19 Mio.
  • Verkaufte Windows Phones: 1,702 Mio.
  • Marktanteil Windows Phone: 1,48%

Q4/2011:

  • Verkaufte Smartphones: 149,19 Mio.
  • Verkaufte Windows Phones: 2,759 Mio.
  • Marktanteil Windows Phone: 1,85%

Hier sind zwei Dinge erkennbar: Der Smartphone-Markt wächst gewaltig, 29.5% mehr Smartphones wurden im letzten Quartal 2011 verkauft als im Quartal zuvor. Doch der Marktanteil von Windows Phone ist stärker gewachsen. Über 62% konnte Windows Phone bei der Anzahl verkaufter Geräte im Quartalsvergleich zulegen und seinen Marktanteil von 1,48% auf 1,85% um 25% steigern!

nokia-logoDas hat Ursachen: im Oktober 2011 wurde Windows Phone Mango veröffentlicht, das viele fehlende Funktionen nachgerüstet hat, z.B. die Internet-Freigabe. Außerdem hat Nokia mit der Lumia-Serie (Lumia 710, Lumia 800) seine ersten Windows Phones auf den Markt gebracht. Mit diesen Geräten und ca. 1 Mio. verkauften Exemplaren konnte sich Nokia direkt an die Spitze der Windows-Phone-Hersteller setzen. Nokia zeigt, was sich mit guter Technologie, elegantem Design und geschickter Werbung auf Basis einer bekannten Marke alles machen lässt.

Was bringt die Zukunft?

Es ist zu hoffen, dass sich Windows Phone als dritte Kraft im Smartphone-Markt etablieren kann und sein Marktanteil weiter steigt. Nicht unbedingt weil ich es persönlich gegenüber Android und iOS bevorzuge, sondern vor allem, weil eine dritte Kraft im Smartphone-Markt dringend notwendig ist. Dass Windows Phone einiges anders macht als iOS und Android (als Nachahmer des iOS-Stils), kann dabei von unschätzbarem Vorteil sein.

Nokia-lumia-6102012 ist ein Jahr der Chancen für Microsoft, um Windows Phone weiter zu etablieren. Mit dem kommenden Tango-Update (inoffizieller Name) werden weitere Sprachen unterstützt, zudem werden die Hardware-Bedingungen gelockert, so dass geringere Systemvoraussetzungen notwendig sind (essentiell für Märkte in Schwellenländern). Das erlaubt vor allem günstigere Windows Phones wie das angekündigte Nokia Lumia 610, das zu einem Preis von ca. 200€ annähernd die komplette Funktionalität von Windows Phone bieten kann.

Spannend wird es dann mit Windows Phone 8 (Codename: Apollo), das noch nicht offiziell angekündigt wurde, über das aber bereits einige inoffizielle Informationen existieren. So soll der Kernel ausgetauscht werden und viele Features wie höhere Auflösungen und Multi-Core-CPUs gehen in die Richtung von Superphones, die als Highend-Geräte unerlässlich sind. Auch die Integration mit Windows 8 ist ein spannendes Thema, das Windows Phone in die Karten spielen kann.

Auch das stetige Wachstum des App-Marketplaces dürfte einen bisherigen Nachteil von Windows Phone gegenüber Android und iOS wettmachen. Fast 70.000 Apps sind für Windows Phone bereits verfügbar, Tendenz steigend. Dass viele Top-Titel der anderen Plattformen noch fehlen, ist nur eine Frage der Zeit…

Insgesamt lässt sich sagen: der vorsichtige Optimismus ist angebracht. Investiert Microsoft weiterhin konsequent in die Entwicklung von Windows Phone, so wird sich das mittelfristig auszahlen. Spätestens im 2. Halbjahr 2012 und in 2013 sollten sich dann größere Erfolge einstellen.

Share |

Anwendungsentwicklung für Tablet-PCs - Eine Standortbestimmung 09.03.2012

Torben Graefe
Torben Graefe, Senior eXpert

Ich erinnere mich noch gut daran, wie ich vor etwa einem Jahr von einem Bekannten wegen meinem 4 Zoll großen Smartphone die etwas schnippische Bemerkung zu hören bekam: “Ein größeres hatten sie wohl nicht im Laden…”. Heutzutage reicht eine kurze Zugfahrt aus, um festzustellen, dass 4 Zoll fast schon Standard sind, wohlgemerkt nicht nur bei den Smartphones, sondern bei den Mobiltelefonen insgesamt. Und zwischen den gebannt auf ihre Smartphones starrenden Zuggästen (ob man das gut oder schlecht findet, steht auf einem anderen Blatt), sind die lässig auf ihren noch größeren Bildschirmen hin und her wischenden Tablet-PC-Ästheten längst keine Exoten mehr, sondern auf dem besten Wege, die zuvor omnipräsenten Business-Notebook-Besitzer zu einer Minderheit werden zu lassen.

Auch wenn ich für meine Impressionen aus dem Zug nicht den Anspruch der Repräsentativität erheben kann, passen diese doch gut zu den Berichten, wonach sich die Verkaufszahlen für Tablet-PCs zwischen 2010 und 2011 von 800.000 Stück auf 2,1 Millionen Stück mehr als verdoppelt haben. Zudem wird für 2012 erwartet, dass jedes zweite verkaufte Handy ein Smartphone ist (Quelle: Golem.de). Mit anderen Worten: Hier ist in 1-2 Jahren ein Massenmarkt herangewachsen, an dem kein Unternehmen mit Endkundengeschäft mehr vorbei kommt. Doch auch innerhalb der Unternehmen wachsen die Begehrlichkeiten nach Software, die sich komfortabel mit touchfähigen Geräten bedienen lässt und auf kurzen Wegen optisch ansprechende Ergebnisse liefert. Manche IT-Abteilung wird es in den nächsten Jahren schwer haben, dem Management zu erklären, warum dieses sich zum Abruf der Unternehmenszahlen durch verschachtelte Menüs im 90er-Jahre-Stil hangeln muss.

Tablet-PCs auf dem Weg ins Unternehmensumfeld

Es ist also an der Zeit, sich mit der Software-Entwicklung für die neuen Geräteklassen zu beschäftigen, von denen sich die Tablet-PCs dank ihrer größeren Darstellungsfläche am besten für die Umsetzung komplexerer Anwendungen und die Visualisierung umfangreicher Datenmengen eignen. Aus diesem Grund sollen Tablet-PCs im Mittelpunkt der im Folgenden angestellten Überlegungen stehen, wobei sich fast alle Aussagen und Empfehlungen ohne weiteres auch auf Smartphones übertragen lassen.

Zu Beginn der Entwicklung einer mobilen Applikation stellt sich die Frage nach den Plattformen, auf denen diese lauffähig sein soll. Momentan teilen Apple (iOS) und Google (Android) den Tablet-Markt fast vollständig untereinander auf, wobei iOS immer den Markt nach wie vor dominiert, aber Android gerade stark im Kommen ist. Im 4. Quartal 2011 hatten das iPad 1+2 einen Markanteil von 57,5%, Android kam auf 39,2% und alle anderen Betriebssysteme lagen zusammen bei nur etwas über 3% (Quelle: heise.de). Diese überschaubare Marktsituation bringt es mit sich, dass es in den meisten Fällen hinreichend ist, eine Applikation für iOS und Android zu entwickeln, wenn man sich nicht sogar für eines der beiden Systeme entscheidet, was im Unternehmensumfeld natürlich leichter fällt, als wenn man annähernd die Hälfte seines potentiellen Kundenkreises von vorneherein ausschließt.

Plattformübergreifend in die Zukunft dank HTML5

Deswegen gibt es inzwischen eine ganze Reihe von Frameworks für die parallele Entwicklung von Applikationen für mehrere Plattformen. Idealerweise sollte man damit die gleiche Applikation quasi mit einem Klick für mehrere Plattformen, das heißt, zumindest für iOS und Android, kompilieren können. HTML5 ist in diesem Zusammenhang nicht mehr ein Buzz-Word sondern das Zauberwort, weil auf keinem dieser Geräte eine hoffnungslos veraltete Browser-Engine vom Schlage eines Internet Explorer 6 ihr Werk verrichtet - das wäre dann die gute Nachricht.

Die schlechte Nachricht ist, dass eine HTML5-Applikation damit noch längst nicht “genauso gut” auf allen populären Tablets läuft, weil es zwischen den Geräten beträchtliche Unterschiede gibt, nicht nur bei der Unterstützung des nicht finalisierten HTML5-Standards, sondern auch bezüglich Ausführungsgeschwindigkeit, Auflösung und Seitenverhältnis. Zu allem Überfluss lassen sich Tablets auch noch vom breiten “Landscape”-Modus in den hohen “Portrait”-Modus drehen, was dramatische Folgen für das Layout einer laufenden Anwendung haben kann und die Unterschiede zwischen 4:3-Displays und 16:9-Displays noch verstärkt. Und wer gewährleistet mir, dass meine Anwendung mit dem Framework, für das ich mich entschieden habe, in Zukunft auch auf Tablets mit Windows 8 laufen wird? Was ist eigentlich, wenn mit der nächsten Tablet-Generation auch die Auflösungen spürbar ansteigen? Skaliert meine Anwendung dann mit oder werden all die verstecken Browserschranken, die mein Framework-Anbieter eingebaut hat, bis zum nächsten großen Update dafür sorgen, dass ein substantieller Teil der Benutzer meine Anwendung nur in der Miniaturansicht zu sehen bekommt?

Alle diese Fragestellungen zeigen vor allem eines: Die Situation ist und bleibt in nächster Zeit trotz der millionenfach verkauften und millionenfach genutzten mobilen Endgeräte unübersichtlich. Deswegen bauen wir in der SDX momentan verstärkt Know-How in der Entwicklung von Frameworks auf, die direkt im Browser des jeweiligen Mobilgerätes laufen, also nicht von einer nativen “Ummantelung” abhängig sind. Die populärsten Vertreter dieser Art von Frameworks sind jQuery Mobile und Sencha Touch, über die es an dieser Stelle demnächst mehr zu lesen geben wird.

Share |

System Center Advisor ist da!

Nicolas Meseth
Nicolas Meseth, Senior eXpert
Finde ich persönlich eine sehr coole Anwendung: Es gibt einen Dienst von Microsoft, den System Center Advisor, bei dem man sich anmelden kann und seine SQL Server 2008 (R2) Konfiguration proaktiv überwachen lassen kann. Das ganze lief lange unter dem Codename "Project Atlanta". Der System Center Advisor ist gespickt mit Informationen über Optimierungsmaßnahmen für verschiedene Konfigurationsszenarien und gibt diese Informationen gerne an den Anwender weiter.

"System Center Advisor is a cloud service hosted on Windows Azure that regularly analyzes your servers’ configuration, drawing on the wisdom and experience of Microsoft support staff and its countless interactions with IT professionals to automatically highlight server configuration problems and their solutions for Windows Server and SQL Server" (Quelle: Microsoft Server and Cloud Platform)
Das ganze basiert auf Azure und Silverlight und bietet eine sehr nette Oberfläche, auf der man direkt die wichtigsten Meldungen bezüglich seiner Server-Farm einsehen kann. Genauer wird es in diesem Video erklärt und gezeigt.

Es gibt eine Trial Version für 60 Tage. Ansonsten kommt der Dienst mit der Software Assurance für SQL Server oder Windows Server
"You can evaluate System Center Advisor now through the 60 day free trial. If your organization is already covered by Software Assurance on either SQL Server or Windows Server you can activate the full Adivsor Service immediately."
Der System Center Advisor unterstützt übrigens nicht nur den SQL Server, sondern auch Windows Server 2008 bzw 2008 R2.
Share |

SQL Server 2012 Released to Manufacturing 07.03.2012

Viktor Ewert
Viktor Ewert, Senior eXpert
Share |

Instant File Initialization für SQL Server

Daniel Tonagel
Daniel Tonagel, Chief eXpert

Große Datenbanken leben in großen Dateien. Manchmal müssen diese Dateien neu angelegt oder erweitert werden, z.B. bei neuen Datenbankinstanzen, Restores, Kapazitätserweiterungen und ähnlichem. Um diese Vorgänge zu beschleunigen, bietet der SQL Server seit Version 2005 ein interessantes Feature an.

Sofortige Dateiinitialisierung

Eigentlich handelt es sich um ein Betriebssystem-Feature, das seit Windows Server 2003 bzw. Windows XP vorhanden ist, nämlich die sofortige Dateiinitialisierung. Was hat es damit auf sich?

Normalerweise werden Windows-Dateien beim Erzeugen mit Nullen initialisiert. Bei großen Dateien kann das naturgemäß etwas dauern. Die Datenbankdateien des SQL Servers werden in ihrer internen Struktur jedoch ohnehin von dessen eigenem Page/Extent-System verwaltet, d.h. der SQL Server liest nichts, was er nicht vorher selbst geschrieben hat, weshalb die Initialisierung unnötig ist. OK, das ist nicht die ganze Wahrheit, aber dazu gleich mehr.

Für's erste kann man mitnehmen, das sich mit diesem Feature eine ganze Reihe von Vorgängen signifikant verkürzen lässt. Bei einem Restore beispielsweise kann sich die benötigte Zeit fast verdoppeln, weil die Datendateien ohne die Instant Initialization zweimal geschrieben werden. Erst werden sie mit Nullen gefüllt, dann vom eigentlichen Restore überschrieben. Den ersten Schritt kann man mit diesem Feature komplett überspringen.

Geschwindigkeit auf Kosten der Sicherheit?

Schön, aber warum ist das nicht von vorneherein aktiviert, wenn es so nützlich ist? Weil es ein (kleines) Sicherheitsrisiko darstellt. Eine nicht initialisierte Datei kann Daten enthalten, die aus zuvor gelöschten Dateien stammen und jeder, der die Datei lesen darf, hat Zugriff auf diese Datenblöcke. Das ist im SQL Server Kontext i.d.R. kein Problem.

Auf einem Laufwerk, das für SQL Server Datendateien benutzt wird, haben andere Dateien nämlich ohnehin nichts verloren und Datenfragmente, die aus zuvor gelöschten anderen DB-Dateien stammen, waren bereits im Zugriff des SQL Service Accounts. Auslesen ließen sich solche Datenfragmente aus gelöschten Dateien übrigens mit dem (undokumentierten) DBCC PAGE Befehl, mit dem man beliebige Blöcke aus den SQL Datendateien lesen kann (entsprechende Rechte vorausgesetzt). Die Gefahr, das ehemals gelöschte Daten aber z.B. wieder in aktuellen Tabellen auftauchen, besteht jedoch nicht.

Wer ganz auf Nummer Sicher gehen will, löscht Dateien auf den betroffenen Laufwerken erst nach einmaligem Überschreiben mit Nullen - dafür gibt es diverse, frei verfügbare Tools. Löschen ist normalerweise weniger zeitkritisch als das Anlegen neuer Dateien.

Konfiguration

Wie schaltet man diese Feature nun an? Ganz einfach, man gibt dem SQL Server Service Account das Windows-Recht "Perform Volume Maintenance Task" (SE_MANAGE_VOLUME_NAME) und startet die Instanz neu. Der SQL Server prüft, ob er dieses Recht hat und nutzt davon abhängig automatisch das Initialisierungsfeature. Standardmäßig ist das Recht nur auf Administratoraccounts aktiv, während der SQL Server entweder unter einem eigens angelegten Service Account oder - ebenfalls beliebt - unter "Network Service" läuft.

Zu bemerken wäre noch, dass das Feature nur bei Datendateien greift, nicht bei Logdateien. Letztere werden auf jeden Fall initialisiert, da sie zyklisch beschrieben werden und keine feste Initialstruktur an einer bestimmten Stelle haben.

Share |

Herzlichen Glückwunsch! Der Gewinner des Nokia Lumia’s steht fest! 02.03.2012

Svenja Henß
Svenja Henß, Senior Assistant

Vielen Dank für die zahlreichen Teilnahmen an unserem Gewinnspiel zum SQL Server Launch in Köln!

Es waren wirklich sehr kreative, lustige und außergewöhnliche Fotos dabei. Die Entscheidung fiel uns nicht leicht.

Nun steht das Gewinnerfoto fest:

$RV2RSZG

Herzlichen Glückwunsch an Marcus H. aus Frankfurt!

Viele Grüße aus dem SDX Office und ein schönes Wochenende.

Share |