View
217
Download
1
Embed Size (px)
SQL Tipps und TricksSQL Tipps und Tricks
1/48
PHP-User-Group Stuttgart
09.06.201009.06.2010
SQL Tcken im Alltag mit MySQL und anderen Datenbanken
Performance, Tuning und was man dafr hlt..
praktische Problemlsungen mit SQL
Lsungen rund um GROUP BY, NULLs und Tuning
SQL-Standards kennen
SQL Tipps und TricksSQL Tipps und Tricks
2/48
Thomas Wiedmann
> 21 Jahre Problemlsungen in der Softwareentwicklung
Seit sieben Jahren Projekte mit PHP und Oracle PL/SQL bzw. DB2/NT
Zend Certified PHP Engineer (ZCE)
IBM Certified Solution Expert - DB2 UDB v7.1 Database Administration
Autor diverser Fachartikel in der Toolbox und im PHP-Magazin
Autor des Buches DB2 SQL, Programmierung, Tuning 2001
Weitere Prsentationen und Tutorials auf meiner Homepage
http://www.twiedmann.de
Wer bin ich ?Wer bin ich ?Wer bin ich ?Wer bin ich ?
SQL Tipps und TricksSQL Tipps und Tricks
3/48
NULL zu NULL Spielereien
MySQL - GROUP BY oder was man dafr hlt..
MySQL - Server Modus berraschung beim Kunden
Daten schnell? in die Datenbank einlesen
MySQL Ein rasantes Ranking erzeugen
MySQL - Tuning mit GROUP BY
Design und Datenbank-Migrations Hinweise
berblickberblickberblickberblick
SQL Tipps und TricksSQL Tipps und Tricks
4/48
Spass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL Werten
CREATE TABLE test_null ( wert INT);INSERT INTO test_null VALUES ( NULL ), ( NULL );SELECT COUNT(wert) * 4 AS anzahl FROM test_null;------------------------------------------------Welcher Wert wird fr die Spalte anzahl ermittelt?
a) 1b) 4c) 8d) nichts von alledem
SQL Tipps und TricksSQL Tipps und Tricks
5/48
Spass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL Werten
SELECT COUNT(wert) * 4 AS anzahl FROM test_null;+--------+| anzahl |+--------+| 0 |+--------+Warum ist das so?
COUNT(NULL) * 4 rechnet sich wie finde nichts * 4 = 0
Beim CREATE TABLE also - wenn mglich und sinnvoll - alleSpalten mit dem NOT NULL Constraint definieren.
- spart Probleme- spart Platz ( MyISAM Engine bentigt bei NULL Spalten ein Byte mehr)
SQL Tipps und TricksSQL Tipps und Tricks
6/48
Spass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL Werten
CREATE TABLE test_null_2 ( col1 INT NOT NULL, col2 INT);
INSERT INTO test_null_2 VALUES ( 1, NULL );
Wie kann exakt dieser Datensatz wieder gelesenwerden?
SQL Tipps und TricksSQL Tipps und Tricks
7/48
Spass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL Werten
SQL Tipps und TricksSQL Tipps und Tricks
8/48
Spass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL WertenSpass mit NULLs und NULL Werten
SQL Tipps und TricksSQL Tipps und Tricks
9/48
NULL versus NOT NULL
NULL - bedeutet undefiniert bzw. keine Ahnung
NULL - kann nur mit IS NULL korrekt geprft werden
NOT NULL - mehr Probleme beim Einfgen und ndern
NOT NULL - garantiert bessere Datenqualitt
NULL wird beim ORDER BY unterschiedlich behandeltvon den verschiedenen Datenbanken
Zusammenfassung NULLsZusammenfassung NULLsZusammenfassung NULLsZusammenfassung NULLs
SQL Tipps und TricksSQL Tipps und Tricks
10/48
+----------+--------------+--------+| kunde_id | vertreter_id | betrag |+----------+--------------+--------+| 10 | 1 | 100.00 || 10 | 2 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+--------+SELECT kunde_id, vertreter_id, MAX(betrag) FROM kunde_umsatz GROUP BY kunde_id;+----------+--------------+-------------+| kunde_id | vertreter_id | MAX(betrag) |+----------+--------------+-------------+| 10 | 1 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+-------------+
MySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisseMySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisse
SQL Tipps und TricksSQL Tipps und Tricks
11/48
+----------+--------------+--------+| kunde_id | vertreter_id | betrag |+----------+--------------+--------+| 10 | 1 | 100.00 || 10 | 2 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+--------+SELECT kunde_id, vertreter_id, MAX(betrag) FROM kunde_umsatz GROUP BY kunde_id;+----------+--------------+-------------+| kunde_id | vertreter_id | MAX(betrag) |+----------+--------------+-------------+| 10 | 1 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+-------------+
MySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisseMySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisse
SQL Tipps und TricksSQL Tipps und Tricks
12/48
+----------+--------------+--------+| kunde_id | vertreter_id | betrag |+----------+--------------+--------+| 10 | 1 | 100.00 || 10 | 2 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+--------+SELECT kunde_id, vertreter_id, MAX(betrag) FROM kunde_umsatz GROUP BY kunde_id;+----------+--------------+-------------+| kunde_id | vertreter_id | MAX(betrag) |+----------+--------------+-------------+| 10 | 1 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+-------------+
MySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisseMySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisse
MySQL liefert falsche
Ergebnisse ?!?
SQL Tipps und TricksSQL Tipps und Tricks
13/48
+----------+--------------+--------+| kunde_id | vertreter_id | betrag |+----------+--------------+--------+| 10 | 1 | 100.00 || 10 | 2 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+--------+SELECT kunde_id, vertreter_id, MAX(betrag) FROM kunde_umsatz GROUP BY kunde_id;+----------+--------------+-------------+| kunde_id | vertreter_id | MAX(betrag) |+----------+--------------+-------------+| 10 | 1 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+-------------+
MySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisseMySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisse
ungltigerGROUP BY !!
SQL Tipps und TricksSQL Tipps und Tricks
14/48
+----------+--------------+--------+| kunde_id | vertreter_id | betrag |+----------+--------------+--------+| 10 | 1 | 100.00 || 10 | 2 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+--------+SELECT u.kunde_id, u.vertreter_id, g.max_betrag FROM kunde_umsatz u JOIN ( SELECT kunde_id, MAX(betrag) AS max_betrag FROM kunde_umsatz GROUP BY kunde_id ) g ON u.kunde_id = g.kunde_id AND u.betrag = g.max_betragORDER BY kunde_id;+----------+--------------+------------+| kunde_id | vertreter_id | max_betrag |+----------+--------------+------------+| 10 | 2 | 200.00 || 20 | 1 | 300.00 || 30 | 2 | 300.00 |+----------+--------------+------------+
MySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisseMySQL - GROUP BY ErMySQL - GROUP BY Er[[ g g || l l ]]ebnisseebnisse
SQL Tipps und TricksSQL Tipps und Tricks
15/48
Mglichkeiten MySQL zu zwingen eher ANSI-SQL zu verarbeiten.(durch Anpassen des SQL-Modus des Servers)
ONLY_FULL_GROUP_BY
Nur Spalten der GROUP BY-Klausel drfen direkt in der Select-Liste stehen. Fr alle anderen mssen Aggregatfunktionenwie MIN(), MAX(), COUNT(), SUM() etc. angewendet werden.
ANSI
ndert Syntax und Verhalten so, dass eine hhere Kompatibilitt mit Standard-SQL erzielt wird. ANSI enthlt folgende Modi: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE
mehr Details dazu siehe 5.2.5. Der SQL-Modus des Servers
MySQL - SQL Modus und GROUP BYMySQL - SQL Modus und GROUP BYMySQL - SQL Modus und GROUP BYMySQL - SQL Modus und GROUP BY
SQL Tipps und TricksSQL Tipps und Tricks
16/48
MySQL - SQL Modus [global] oder [session] ermitteln
Die Einstellung der GLOBAL-Variable erfordert die Berechtigung SUPER und wirkt sich auf den Betrieb aller Clients aus, die nachfolgend eine Verbindung herstellen. Von der nderung der SESSION-Variable ist nur der aktuelle Client betroffen. Jeder Client kann jederzeit seinen eigenen sql_mode-Sitzungswert ndern. MySQL Handbuch
SELECT @@global.sql_mode;SELECT @@session.sql_mode;
mysql> SELECT @@global.sql_mode;+-------------------+| @@global.sql_mode |+-------------------+| |+-------------------+
MySQL - SQL Modus und GROUP BYMySQL - SQL Modus und GROUP BYMySQL - SQL Modus und GROUP BYMySQL - SQL Modus und GROUP BY
SQL Tipps und TricksSQL Tipps und Tricks
17/48