14. But...
• id is AUTO_INCREMENT, so it’s 1
• let’s run that again
mysql> CREATE TABLE t (
‐> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT
‐> );
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t (id)
‐> VALUES (NULL);
Query OK, 1 row affected (0.04 sec)
mysql> SELECT *
‐> FROM t
‐> WHERE id IS NULL;
+‐‐‐‐+
| id |
+‐‐‐‐+
| 1 |
+‐‐‐‐+
29. There is a better way
CREATE DEFINER=`root`@`localhost` PROCEDURE `pref_index`(t_name CHAR(255), c_name CHAR(255))
BEGIN
DECLARE plength INT DEFAULT 1;
SET @q = CONCAT('SELECT CHARACTER_MAXIMUM_LENGTH INTO @maxlen
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = quot;world2quot; AND
TABLE_NAME = quot;',
t_name,'quot; AND
COLUMN_NAME = quot;',
c_name, 'quot;');
PREPARE q FROM @q;
EXECUTE q;
DEALLOCATE PREPARE q;
REPEAT
SET @qq = CONCAT('SELECT COUNT(*) ‐ COUNT(DISTINCT ',c_name,')
into @dupe FROM ',t_name);
SET @pq = CONCAT('SELECT COUNT(*) ‐ COUNT(DISTINCT LEFT(',c_name,',',plength,'))
into @pdupe FROM ',t_name);
PREPARE qs FROM @qq;
EXECUTE qs;
DEALLOCATE PREPARE qs;
PREPARE ps FROM @pq;
EXECUTE ps;
DEALLOCATE PREPARE ps;
SET plength = plength + 1;
UNTIL plength >= @maxlen OR @pdupe = @dupe
END REPEAT;
SELECT plength, @pdupe, @dupe;
END
46. External tools
• mysqlsla
http://hackmysql.com/mysqlsla
mysqlsla parses, filters, analyzes and
sorts MySQL slow, general, binary and
microslow patched logs in order to
create a customizable report of the
queries and their meta-property values.
47. External tools
• mysqlidxchk
http://hackmysql.com/mysqlidxchk
mysqlidxchk (MySQL Index Checker)
checks MySQL databases/tables for
unused indexes. Given one or more
slow, general, or quot;rawquot; log files,
mysqlidxchk reports which indexes in
the database schema are not used by
the queries in the log files.
63. Instead, split in two
select d.dept_name, SUM(salary) from departments d
LEFT JOIN dept_emp de USING (dept_no) LEFT JOIN
salaries s USING (emp_no) where s.from_date >=
'2000‐01‐01' and s.to_date < '2001‐01‐01' group by
dept_no;
CREATE TEMPORARY TABLE salaries2000
SELECT * FROM salaries s
WHERE s.from_date >= '2000‐01‐01'
AND s.to_date < '2001‐01‐01';
SELECT d.dept_name, SUM(salary)
FROM departments d
LEFT JOIN dept_emp de USING (dept_no)
LEFT JOIN salaries2000 s USING (emp_no)
GROUP BY dept_no;
70. mysql> select * from t;
+‐‐‐‐+
| id |
+‐‐‐‐+
| 1 |
+‐‐‐‐+
1 row in set (0.00 sec)
WTF?!?
mysql> create temporary table t(id int);
...again
Query OK, 0 rows affected (0.08 sec)
mysql> select * from t;
Empty set (0.00 sec)
mysql> insert into t values (2);
Query OK, 1 row affected (0.05 sec)
mysql> select * from t;
+‐‐‐‐‐‐+
| id |
+‐‐‐‐‐‐+
| 2 |
+‐‐‐‐‐‐+
1 row in set (0.00 sec)
71. • Temporary tables exist per session
• Be careful using connection pools
• They overlap current tables
72. There’s a reason for everything
mysql> select * from t;
+‐‐‐‐‐‐+
| id |
+‐‐‐‐‐‐+
| 2 |
+‐‐‐‐‐‐+
1 row in set (0.00 sec)
temporary
mysql> drop table t;
Query OK, 0 rows affected (0.04 sec)
mysql> select * from t;
+‐‐‐‐+
| id |
+‐‐‐‐+
| 1 |
+‐‐‐‐+
regular
1 row in set (0.00 sec)
mysql> drop table t;
Query OK, 0 rows affected (0.00 sec)
mysql> drop table t;
ERROR 1051 (42S02): Unknown table 't'
73. What else?
• MySQL Proxy
https://launchpad.net/mysql-proxy
• MySQL Sandbox
https://launchpad.net/mysql-sandbox
• MySQL Random Query Generator
https://launchpad.net/randgen