Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Большой объем даных в MySQL - медленно выполняется запрос
 
 автор: alex_fear   (04.03.2011 в 10:00)   письмо автору
 
 

Добрый день!
Кто сталкивался с такой проблемой.
Есть база данных в MySQL обем данніх 700мб и 20 000 000 записей!
Делаю запрос по віборке сервер просто зависает!
Реально ли єто как то оптимизировать?
Говорят можно базу в InnoDB держать!

  Ответить  
 
 автор: cheops   (04.03.2011 в 10:55)   письмо автору
 
   для: alex_fear   (04.03.2011 в 10:00)
 

>Добрый день!
>Кто сталкивался с такой проблемой.
>Есть база данных в MySQL обем данніх 700мб и 20 000 000 записей!
>Делаю запрос по віборке сервер просто зависает!
>Реально ли єто как то оптимизировать?
1) Покажите запрос и структуру таблиц, к которым делаете запрос (SHOW CREATE TABLE)?
2) У вас таблицы индексированы, если индексированы, то как?

>Говорят можно базу в InnoDB держать!
Будет еще медленее, причем в разы.

  Ответить  
 
 автор: alex_fear   (04.03.2011 в 12:13)   письмо автору
 
   для: cheops   (04.03.2011 в 10:55)
 

CREATE TABLE `kat_atg` (
`ATG` char(4) CHARACTER SET cp1251 COLLATE cp1251_general_cs NOT NULL,
`ART` char(4) CHARACTER SET cp1251 COLLATE cp1251_general_cs NOT NULL,
`TYP` int(5) NOT NULL,
`WSK` char(1) NOT NULL,
`GEN` int(5) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=cp1251

  Ответить  
 
 автор: cheops   (04.03.2011 в 12:18)   письмо автору
 
   для: alex_fear   (04.03.2011 в 12:13)
 

А запрос какой (который подвисает)?

PS В любом случае видно, что индексов нет - поэтому все так и медленно, MySQL вынуждена каждый раз перелопачивать 700Мб данных (за исключением запросов без WHERE-условия). Обычно для наиболее популярных SELECT-запросов создают индексы, которые хранят номера строк в отдельном файле в отсортированом порядке, когда SELECT-запрос получает возможность использования такого индекса - он выполняется очень быстро, без сканирования целевой таблицы.

  Ответить  
 
 автор: alex_fear   (04.03.2011 в 13:23)   письмо автору
 
   для: cheops   (04.03.2011 в 12:18)
 


$typ='19902';
$gen='301010000';
mysql_query("CREATE TEMPORARY TABLE `t_kat_tg` (`GEN` int(5) NOT NULL)");
mysql_query("INSERT INTO `t_kat_tg` SELECT DISTINCT `GEN` FROM `kat_tg` WHERE TYP=$typ");
mysql_query("CREATE TEMPORARY TABLE `t_kat_gen` (`GEN` int(5) NOT NULL,`GRU` int(10) NOT NULL,`NAZ`  varchar(1000) CHARACTER SET cp1251 COLLATE cp1251_general_cs NOT NULL)");
mysql_query("INSERT INTO `t_kat_gen` SELECT  T2.GEN, T2.GRU, T2.NAZ FROM `t_kat_tg` AS T1, `kat_gen` AS T2 WHERE T2.GEN = T1.GEN");


$result40=mysql_query("SELECT * FROM `t_kat_gen`  WHERE `GRU`=$gen ");
                                              while($data=mysql_fetch_array($result40, MYSQL_ASSOC)){



$naz=mysql_real_escape_string($data['NAZ']);
$result4=mysql_query("SELECT * FROM `kat_naz`  WHERE `NAZ`='$naz'");



                                              while($data1=mysql_fetch_array($result4, MYSQL_ASSOC)){


//print_r($data1);

$result2=mysql_query("SELECT * FROM `kat_atg`  WHERE `TYP`='$typ' and `GEN`='$gen'");



                                              while($data2=mysql_fetch_array($result2, MYSQL_ASSOC)){


print_r($data2);
}

  Ответить  
 
 автор: cheops   (04.03.2011 в 13:34)   письмо автору
 
   для: alex_fear   (04.03.2011 в 13:23)
 

Насколько много записей выводится запросом
SELECT * FROM `kat_atg`
WHERE `TYP`='$typ' and `GEN`='$gen'

Нет ли смысла применить здесь постраничную навигацию?

  Ответить  
 
 автор: alex_fear   (04.03.2011 в 13:55)   письмо автору
 
   для: cheops   (04.03.2011 в 13:34)
 

От 5 до 12

  Ответить  
 
 автор: cheops   (04.03.2011 в 14:00)   письмо автору
 
   для: alex_fear   (04.03.2011 в 13:55)
 

У вас получается три вложенных цикла, причем две таблицы создаются искусственно перед этим. Лучше всего избавиться от временных таблиц (и необходимости их заполнения), а также свести 3 вложенных цикла к одному. После индексации таблицы, я думаю можно будет добиться существенного сокращения времени обработки запроса.

  Ответить  
 
 автор: cheops   (04.03.2011 в 13:34)   письмо автору
 
   для: alex_fear   (04.03.2011 в 13:23)
 

В первую очередь в таблице kat_atg создайте индексы по столбцам TYP и GEN
CREATE INDEX `TYP` ON kat_atg (`TYP`);
CREATE INDEX `GEN` ON kat_atg (`GEN`);

  Ответить  
 
 автор: cheops   (04.03.2011 в 13:36)   письмо автору
 
   для: alex_fear   (04.03.2011 в 13:23)
 

Есть ли надобность в создании временных таблиц? INSERT-запрос это достаточно дорогой запрос, а временные таблицы не обязательно располгаются в оперативной памяти, они могут быть сброшены на жесткий диск. Ведь многие задачи можно решить самообъединением таблицы, присвоив одной и той же таблице в многотабличном запросе разные псевдонимы.

  Ответить  
 
 автор: alex_fear   (04.03.2011 в 15:19)   письмо автору
 
   для: cheops   (04.03.2011 в 13:36)
 

как правильно создать интексы делаю индех по другой таблице
[SQL] CREATE INDEX `TYP` ON kat_tg (`TYP`);
[Err] 1061 - Duplicate key name 'TYP'
Вот что выдает в чом проблема?
И как их вобще создавать?
Сначала таблицу и создать индексы а потом данные заливать? Или после заливки данных?

  Ответить  
 
 автор: cheops   (04.03.2011 в 15:32)   письмо автору
 
   для: alex_fear   (04.03.2011 в 15:19)
 

1) Погодите, а kat_tg какую структуру имеет (SHOW CREATE TABLE kat_tg)?
2) В ней уже есть индексы с именем TYP?
3) kat_tg это обычная таблица или временная?

  Ответить  
 
 автор: alex_fear   (05.03.2011 в 09:59)   письмо автору
 
   для: cheops   (04.03.2011 в 15:32)
 

Это обычная таблица!
И как запрс выполнять! Если проиндексированы столбцы? Также как и обычный?

  Ответить  
 
 автор: cheops   (05.03.2011 в 10:07)   письмо автору
 
   для: alex_fear   (05.03.2011 в 09:59)
 

Да, также как обычный, СУБД сама будет использовать индекс, если у неё будет такая возможность.

  Ответить  
 
 автор: alex_fear   (05.03.2011 в 10:22)   письмо автору
 
   для: cheops   (05.03.2011 в 10:07)
 

Можно как то эт временные таблицы обойти?

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования