Monatsarchiv für Januar 2009

Seit letzter Woche ist mein Team im Besitz einer Demo Lizenz von Atlassian JIRA. Der Anfang war nicht ganz Simple (Installation, Anbidung an unser LDAP etc.) aber wo es jetzt erst einmal läuft und wir das erste Projekt damit fahren möchte ich es nicht mehr missen.
Ein Bugtracker ist zwar sicherlich keine unternehmenskritische Software, aber im Projektgeschäft einfach unentbehrlich. Nachdem ich schon mehrer Tools (sowohl freie als auch kommerzielle) in diesem Umfeld kennen lernen durfte, muss ich ganz ehrlich sagen dass mich JIRA bisher am meisten überzeugen kann und sein Geld durchaus wert ist. Mal sehen ob das in einigen Wochen auch noch so ist.

Nachdem ich im ersten Teil dieser kleinen Reihe geschrieben hatte, wie die Datenbankengine verschiedene Indixes benutzt, will ich in diesem zweiten Teil versuchen klar zu machen bei welchen Statement welcher Index überhaupt verwendet werden kann.
Auch hier will ich noch mal grob vereinfachen und mit einfachen Statements auf eine Tabelle beginnen.
Die Verarbeitungszeit steht ja praktisch immer in Bezug zu er Menge an Datensätzen, deswegen, versucht die Datenbank die Menge an zu verarbeitenden Daten möglichst schnell möglichst klein zu bekommen.

Im folgenden gehe ich von folgender Tabelle aus

Spaltenname Typ Index
EMPLOYEENO VARCHAR IDX_EMOLOYEENO AS UNIQUE INDEX ON EMPLOYEENO
NAME VARCHAR IDX_EMLOYEENAME AS INDEX ON NAME, FIRSTNAME
FIRSTNAME VARCHAR IDX_EMLOYEENAME AS INDEX ON NAME, FIRSTNAME
EMAIL VARCHAR IDX_EMLOYEEEMAIL AS INDEX ON EMAIL
JOB VARCHAR (kein Index)
SALARY NUMBER IDX_SALARY AS INDEX ON (SALARY)

Hier ein paar Faustregeln wann welcher Cache verwendet wird:

  • Hat eine Spalte in der SQL Abfrage einen Eindeutigen Index so wird dieser verwendet. Das gilt auch wenn noch andere mit AND verknüpfte Spalten in dem Statement auftauchen
    Beispiel: SELECT * FROM EMPLOYEE WHERE EMPLOYEENO=4711 AND NAME like 'Herbst%' verwendet immer den eindeutigen Index über die EMPLOYEENO.
  • Hat eine Spalte einen Index und wird mit einer Gleichheitsbedingung verwendet, so wird dieser Index herangezogen
    Beispiel: SELECT * FROM EMPLOYEE WHERE SALARY='32000' verwendet immer den eindeutigen Index über SALARY.
  • Abfragen nach Texten können einen Index nur bis zur ersten Wildcard verwenden.
    Beispiel: SELECT * FROM EMPLOYEE WHERE EMAIL LIKE 'joerg.herbst%' verwendet den Index über auf Email , da es sich um einen normalen Text Index handelt und die Wildcard an der rechten grenze steht.
    SELECT * FROM EMPLOYEE WHERE EMAIL LIKE '%@gish.de' verwendet keinen Index da die Wildcard links steht.
  • Ein mehrspaltiger Index kann nur verwendet werden wenn alle Index Spalten auch im Suchstatement vorhanden sind. Dabei werden die spalten von Links nach rechts ausgewertet.
    Beispiel:
    SELECT * FROM EMPLOYEE WHERE NAME='Herbst' AND FIRSTNAME='Joerg'
    verwendet den Index auf NAME.
    SELECT * FROM EMPLOYEE WHERE NAME='Mueller'
    verwendet den Index auf NAME.
    SELECT * FROM EMPLOYEE WHERE FIRSTNAME='Stephan'
    verwendet keinen Index.
    SELECT * FROM EMPLOYEE WHERE LASTNAME='Mueller' AND FIRSTNAME LIKE ='St%'
    verwendet den  Index.
  • Wendet man SQL Funktionen wie UPPER, LOWER etc. auf eine Tabellenspalte an kann grundsätzlich kein Index benutzt werden.
    Beispiel: SELECT * FROM EMPLOYEE WHERE LOWER(EMAIL)='max.muster@web.de' verwendet keinen Index und muss einen Full Table Scan machen.

Nachdem zur zeit Webdesign mit runden (abgerundeten) Ecken immer populärer werden, war ich auf der Suche nach einer Lösung für dieses Problem. Während Firefox ja schon seit einigen Versionen eine properitäre (-moz-border..) bietet bleibt die Mehrheit der Internet (Explorer) Nutzer immer noch ausgesperrt. Hier helfen nur zwischen Lösungen mit einer oder mehreren Hintegrundgrafiken für die es hunderte Beispiele im Web gibt. Alle diese Lösungen sind aber mehr oder minder schwierig zu warten und erfordern eine Menge überflüssiges HTML und Grafik Dateien.
Gott sei Dank geht es auch einfacher. Bei meiner momentanen Liebingsjava Script Bibliothek jquery gibt es ein “corner” Plugin, das neben den hübschen aberundeten Ecken auch gleich noch einiges anderes mehr kann.