Mittwoch, Juni 30, 2010

Interne Repräsentation von Number-Werten

Auf Steve Adams ixora-Seite findet man eine kurze Erläuterung zur internen Repräsentation von NUMBER-Werten. Die interne Darstellung entspricht einer wissenschaftlichen Notation mit Exponent und Mantisse. Dabei enthält das erste Byte der Repräsentation ein Bit für das Vorzeichen und den Exponenten, dann folgt die Mantisse, wobei jedes Byte normalerweise zwei Dezimalstellen darstellt. Mit der Funktion DUMP kann man die interne Repräsentation einer Zahl darstellen lassen:

select dump(1.23) from dual;

DUMP(1.23)
---------------------
Typ=2 Len=3: 193,2,24

select dump(123) from dual;

DUMP(123)
---------------------
Typ=2 Len=3: 194,2,24

select dump(1230000) from dual;

DUMP(1230000)
---------------------
Typ=2 Len=3: 196,2,24

Der Exponent ändert sich (193 -> 194 -> 196), während die Mantisse identisch bleibt (2, 24). Bei Gelegenheit sollte ich mir die Details noch etwas genauer anschauen.

SQL_TRACE für Einzelstatements

noch ein Link - eigene Gedanken mache ich mir dieser Tage nicht ...
Diesmal auf Tanel Poders Blog, in dem er erwähnt, dass es in 11.2 möglich ist, SQL Trace für eine bestimmte SQL-Id zu aktivieren. Das sieht dann etwa folgendermaßen aus:

alter session set events 'sql_trace[SQL: 9hb0kku1ncc9b] 
              {callstack: fname opiexe} 
              plan_stat=all_executions,wait=true,bind=true';

Bei Tanel Poder erscheint noch die Option {pgadep: exactdepth 0}, die in meinem System (11.1.0.7.0) nicht funktioniert hat.

Nachtrag 17.11.2011: Maria Colgan beschreibt im Blog der cbo Entwickler das entsprechende Verfahren zur Erstellung eines Optimizer-Traces (Event 10053).

Freitag, Juni 25, 2010

Locks

Und noch eine Referenz auf Jonathan Lewis' Blog, wo er die Matrix der Lock-Typen in Oracle darstellt.

32bit und 64bit

In Jonathan Lewis' Blog findet sich ein sehr interessantes Fallbeispiel, in dem der Umstieg von 32bit auf 64bit zu Problemen mit der Speichernutzung führt.

Three kind of lies

"There are three kinds of lies: lies, damned lies, and statistics."

Benjamin Disraeli (behauptet jedenfalls Mark Twain)

Und was ist mit BI?

SQL Server DMVs

Allmählich komme ich dahinter, dass die Dynamic Management Views (DMVs) des SQL Servers ähnlich viele Details über den Zustand des Systems liefern wie die v$- bzw. dba/all/user-Views in Oracle (was nicht allzu sehr verwundern sollte, da die Speicherung interner Verwaltungsinformationen in Tabellenform meiner Erinnerung nach zu den Anforderungen Codds an ein RDBMS gehört). Die folgenden Analysequeries laufen alle auf Version 2008.

So kann man sich z.B. die teuersten Queries des Datenbank-Caches anzeigen lassen:

select top 50
       SUBSTRING(  st.text
                 , (qs.statement_start_offset/2) + 1
                 , ((CASE qs.statement_end_offset
                          WHEN -1 THEN DATALENGTH(st.text)
                          ELSE qs.statement_end_offset
                     END - qs.statement_start_offset)/2) + 1) AS StatementText
     , qs.last_execution_time
     , qs.execution_count
     , qs.total_elapsed_time/1000000 total_elapsed_sec
     , qs.last_elapsed_time/1000000 last_elapsed_sec
     , qs.total_logical_reads
     , qs.last_logical_reads
     , qp.query_plan
  from sys.dm_exec_query_stats qs
 cross apply sys.dm_exec_sql_text(qs.sql_handle) AS st  
 cross apply sys.dm_exec_query_plan(qs.plan_handle) AS qp  
 order by qs.last_elapsed_time desc

Oder die Queries, für die laut Optimizer Indizes fehlen:

select st.text
     , qp.query_plan
     , qs.*
  from Sys.dm_exec_query_stats qs
 cross apply sys.dm_exec_sql_text(qs.sql_handle) st  
 cross apply sys.dm_exec_query_plan(qs.plan_handle) qp  
 where convert(nvarchar(max), qp.query_plan) like '%MissingIndex%'

Oder die aktuell laufenden Abfragen:

select ses.login_name
     , ses.host_name
     , ses.program_name
     , st.text
     , req.session_id
     , req.start_time
     , req.status
     , req.command
     , req.blocking_session_id
     , req.cpu_time/1000 cpu_secs
     , req.total_elapsed_time/1000 ela_secs
     , req.logical_reads
     , qp.query_plan
  from sys.dm_exec_requests req
 inner join sys.dm_exec_sessions ses
    on req.session_id = ses.session_id
 cross apply sys.dm_exec_sql_text(req.sql_handle) AS st  
 cross apply sys.dm_exec_query_plan(req.plan_handle) AS qp

Oder auch die aktuell verbundenen Sessions

select ses.login_name
     , ses.*
  from sys.dm_exec_sessions ses
 where login_name not in ('sa', 'jira')
 order by ses.login_name

Detailliertere Erläuterungen zu den verwendeten DMVs findet man hier. Auf den untergeordneten Seiten findet man dort auch allerlei Analysequeries.

Mittwoch, Juni 16, 2010

MDX Scope

Mit MDX habe ich mich in den letzten beiden Jahren relativ viel beschäftigt, darüber hier aber noch kein Wort verloren. Dafür gab's mehrere Gründe, die aber - wenn überhaupt - ein andermal genannt werden sollen. Ein wichtiger Punkt ist allerdings, dass mir MDX nicht besonders liegt, und dass ich mir wichtige Details einfach nicht merken kann. Um dem abzuhelfen, versuche ich hier ein paar Notizen abzulegen.

Ein erstes Konzept, das mir regelmäßig Unbehagen verursacht, ist der SCOPE. Ein SCOPE ist ein Teilbereich eines Cubes (also ein Subcube), für den bestimmte Sonderregeln definiert werden. Man kann in ihm Überschreibungen festlegen, also dafür sorgen, dass Kennzahlen im SCOPE anders gefüllt werden als außerhalb des SCOPEs. Interessant ist dabei vor allem das unterschiedliche Verhalten von Basiskennzahlen und berechneten Kennzahlen (calculated measures). Dazu ein Beispiel. Im folgenden MDX-Script wird ein calculated measure test_calc definiert. Außerdem existiert im Cube eine Basiskennzahl test_mat, die zunächst mit NULL gefüllt ist. Beide Kennzahlen werden in einem SCOPE auf Artikelebene überschrieben:

CALCULATE; 

CREATE MEMBER CURRENTCUBE.[Measures].[test_calc]
 AS null, 
VISIBLE = 1  ; 

scope [DIM_PRODUCT].[ITEMID].[ITEMID].members; 
test_calc = 1;
test_mat = 1;
end scope;

In der Artikeldimension (DIM_PRODUCT) sind über Attributbeziehungen mehrere Ebenen definiert: über der Artikelebene liegen mehere Warengruppenebenen. Auf der Ebene der SCOPE-Definition, also auf der Artikelebene (ITEMID), liefern beide Kennzahlen den gleichen Wert:


Auf der übergeordneten Warengruppenebene (ITEMGROUPID LEVEL1) hingegen wird die Basiskennzahl weiter aggregiert, während für die berechnete Kennzahl kein Wert definiert ist:


Der SCOPE bestimmt den Ausschnitt des Würfels, in dem eine neue Berechnungslogik gilt, aber für Basiskennzahlen betrifft die Zuordnung alle höheren Ebenen, während für Calculations keine Aggregation von Werten erfolgt, sondern die Berechnung auf jeder Ebene durchgeführt wird.

Donnerstag, Juni 10, 2010

MINUS und EXCEPT

Noch ein Eintrag zum SQL Server: in dessen SQL-Dialekt fehlt das Schlüsselwort MINUS, mit dem man in Oracle die Elemente einer Menge bestimmen kann, die in der zweiten Menge fehlen. Allerdings fehlt tatsächlich nur das Schlüsselwort - ihm entspricht beim SQL Server EXCEPT:

-- Oracle
select 1 from dual
union
select 2 from dual
minus
select 2 from dual;

-- SQL Server
select 1
union
select 2
except
select 2