Mysql оптимизация при помощи mysqltuner

MySQLTuner (http://mysqltuner.com) представляет собой Perl скрипт,
анализирующий статистику работы MySQL сервера и на ее основе дающий
рекомендации по оптимизации настойки СУБД. И так, скачиваем сам скрипт:

wget http://mysqltuner.com/mysqltuner.pl
chmod +x mysqltuner.pl

запускаем:

perl mysqltuner.pl

вас попросят ввести логин и пароль root-a. В итоге вы получите подобный результат:

——— General Statistics —————————————————
[—] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.1.56
[OK] Operating on 32-bit architecture with less than 2GB RAM
——— Storage Engine Statistics ——————————————-
[—] Status: -Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
[—] Data in MyISAM tables: 104M (Tables: 339)
[—] Data in InnoDB tables: 15M (Tables: 40)
[!!] Total fragmented tables: 90
——— Performance Metrics ————————————————-
[—] Up for: 16d 20h 48m 45s (2M q [1.535 qps], 84K conn, TX: 55B, RX: 429M)
[—] Reads / Writes: 43% / 57%
[—] Total buffers: 106.0M global + 9.2M per thread (500 max threads)
[!!] Allocating > 2GB RAM on 32-bit systems can cause system instability
[!!] Maximum possible memory usage: 4.6G (231% of installed RAM)
[OK] Slow queries: 0% (3/2M)
[OK] Highest usage of available connections: 6% (32/500)
[OK] Key buffer size / total MyISAM indexes: 16.0M/13.9M
[OK] Key buffer hit rate: 100.0% (65M cached / 3K reads)
[OK] Query cache efficiency: 74.4% (1M cached / 1M selects)
[!!] Query cache prunes per day: 626
[OK] Sorts requiring temporary tables: 0% (289 temp sorts / 42K sorts)
[!!] Joins performed without indexes: 52872
[OK] Temporary tables created on disk: 24% (24K on disk / 99K total)
[OK] Thread cache hit rate: 99% (32 created / 84K connections)
[!!] Table cache hit rate: 9% (305 open / 3K opened)
[OK] Open file limit used: 17% (459/2K)
[OK] Table locks acquired immediately: 99% (947K immediate / 947K locks)
[!!] InnoDB data size / buffer pool: 15.1M/8.0M
——— Recommendations ——————————————————
General recommendations:
Run OPTIMIZE TABLE to defragment tables for better performance
Enable the slow query log to troubleshoot bad queries
Adjust your join queries to always utilize indexes
Increase table_cache gradually to avoid file descriptor limits
Variables to adjust:
*** MySQL’s maximum memory usage is dangerously high ***
*** Add RAM before increasing MySQL buffer variables ***
query_cache_size (> 64M)
join_buffer_size (> 2.0M, or always use indexes with joins)
table_cache (> 1024)
innodb_buffer_pool_size (>= 15M)

Обратите свое внимание на рекомендации, и для лучшей работы MySQL внести предложенные изменения в my.cnf

MySQL лог SQL запросов

Добавьте следующие строки в MySQL конфиг(my.cnf), для того, что бы начать собирать логи запросов:

slow-query-log
log-output = TABLE
long_query_time = 1
general-log
expire_logs_days = 1

ну и примеры запросов для получения логов:

select * from mysql.general_log order by event_time desc limit 10;
select * from mysql.slow_log order by start_time desc limit 10;

Php авторизация используя MySQL

Простой PhP скрипт для аутентификации с использованием MySQL. Для начала нам понадобиться MySQL таблица:

CREATE TABLE `logon` (
`userid` int(11) NOT NULL auto_increment,
`useremail` varchar(50) NOT NULL default '',
`password` varchar(50) NOT NULL default '',
`userlevel` int(1) NOT NULL default '0',
PRIMARY KEY (`userid`)
) TYPE=MyISAM

Continue reading

MySQL Импортируем CSV файл

Вместо того, что бы писать скрипт, разбирающий .cvs файл, мы можем воспользоваться штаными средствами MySQL. Если вы собираетесь импортировать файл cvs созданый MS Excel, то для начала вам необходимо удалить заголовки и все пустоты в конце файла. Затем, в консоли MySQL:

load data local infile ‘uniq.csv’ into table tblUniq
fields terminated by ‘,’
enclosed by ‘»‘
lines terminated by ‘\n’
(uniqName, uniqCity, uniqComments)

MySQL ‘too many connections’ error

Вот столкнулся с такой ошибкой —

too many connections

По умолчанию количество одновременных подключений к базе ограничено в 100. Для того, что бы проверить, заходим в консоль MySQL  и выполняем:

mysql> show variables like «max_connections»;

результат:

+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 100   |
+-----------------+-------+

Для того что бы изменить это значение, открываем /etc/my.cnf и в секции [mysqld] добавляем:

max_connections = 200

Выбирайте количество соединений по силам сервера, иначе можно столкнуться с нехваткой памяти и прочими радостями.
 

Оптимизация MySQL

Есть несколько параметров, которые могут поднять производительность MySQL, основные это :

key_buffer_size  — буфер для работы с ключами и индексами
query_cache_size — буфер для работы с очередью
thread_cache_size — указывает количество тредов (threads), уходящих в кеш при отключении клиента. При новом подключении тред (thread) не создается, а берется из кеша, что позволяет экономить ресурсы при больших нагрузках.

Ориентировочно, key_buffer_size должен быть равен 1/8 части всей памяти системы, query_cache_size это 1/4 от всей памяти. thread_cache_size подберите эмпирическим способом, изменяя значение от 4 до 20

MySQL cброс авто инкремента

Функция авто-инкремент очень удобна, с ее помощью удобно выдавать уникальные id номера нашим записям, но бывает так, что возникает необходимость сбросить счетчик, для этого можно воспользоваться следующей функцией:

ALTER TABLE tablename AUTO_INCREMENT = 1

Если же, предположим, вы удалили какую то старую запись и хотите новой присвоить номер удаленной, то можно воспользоваться командой

SET insert_id = необходимый номер;

MySQL Игнорируем дубликаты

Все что нужно, это использовать команду DISTINCT. Как пример, пускай у нас есть такая таблица с марками автомобилей:

SELECT name FROM table
 
name      
----       
Ford     
Mazda      
Fiat  
Ford         
Nissan
Honda     
Honda      
Ford  
Audi         
Saab        

в которой как вы видите есть несколько одинаковых названий. Для того, что бы их убрать, используем DISTINCT:

SELECT DISTINCT name FROM table
 
name      
----       
Ford     
Mazda      
Fiat         
Nissan
Honda      
Audi         
Saab        

MySQL Примеры использования команды JOIN

Концепция использования операции JOIN в MySQL. И так, пускай у нас есть две таблицы. Таблица Table A с лева и таблица Table B с права и в каждой из них есть 4 записи:

id name       id  name
-- ----       --  ----
1  Pirate     1   Rutabaga
2  Monkey     2   Pirate
3  Ninja      3   Darth Vader
4  Spaghetti  4   Ninja

Давайте попоробуем использовать операцию JOIN на этих двух таблицах. И так, первый пример Inner join, оставит нам только то, что есть в Table A и Table B:

SELECT * FROM TableA INNER JOIN TableB
ON TableA.name = TableB.name

id  name       id   name
--  ----       --   ----
1   Pirate     2    Pirate
3   Ninja      4    Ninja

Full outer join — обьединение таблицы Table A с Table B:

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name

id    name       id    name
--    ----       --    ----
1     Pirate     2     Pirate
2     Monkey     null  null
3     Ninja      4     Ninja
4     Spaghetti  null  null
null  null       1     Rutabaga       
null  null       3     Darth Vader

Left outer join — результатом будут все записи из таблицы Table A и в таблице Table B остануться только общие записи, вместо всех остальных будет null:

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name

id  name       id    name
--  ----       --    ----
1   Pirate     2     Pirate
2   Monkey     null  null
3   Ninja      4     Ninja
4   Spaghetti  null  null

Для того, что бы получить все записи из Table A которых нет в Table B мы так же будем использовать Left outer join исключая те значения которые нам не ныжны:

SELECT * FROM TableA
LEFT OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableB.id IS null

id  name       id     name
--  ----       --     ----
2   Monkey     null   null
4   Spaghetti  null   null

Для того, что бы получить набор уникальных значений для Table A и Table B будем использовать full outer join с исключениями:

SELECT * FROM TableA
FULL OUTER JOIN TableB
ON TableA.name = TableB.name
WHERE TableA.id IS null 
OR TableB.id IS null

id    name       id    name
--    ----       --    ----
2     Monkey     null  null
4     Spaghetti  null  null
null  null       1     Rutabaga
null  null       3     Darth Vader