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

Форум MySQL

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

 

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

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: Помогите оптимизировать запрос

Сообщения:  [1-10]   [11-18] 

 
 автор: tAleks   (23.12.2010 в 11:45)   письмо автору
 
   для: lightning.say   (23.12.2010 в 11:23)
 

На местно хостинге, где я размещал свои сайты ранее, было все хорошо. Запросы выполнялись быстро.

  Ответить  
 
 автор: lightning.say   (23.12.2010 в 11:23)   письмо автору
 
   для: tAleks   (22.12.2010 в 21:33)
 

а на другом серваке так же медленно выполняются запросы?

  Ответить  
 
 автор: tAleks   (22.12.2010 в 21:33)   письмо автору
 
   для: Косорылый   (22.12.2010 в 21:14)
 

>Дело в том что при разных запросах при неизменной структуре таблиц будут разные результаты выборки ,в том числе и скорость и количество операций

Проблема в том, что запросы одинаковые. Разница только в положении - один на локальной машне, второй на хостинге.

>Определитесь, сначала, какие основные запросы вам необходимы и оптимизируйте под них
>попробуйте проставить индексы на полях и посмотреть результаты основных запросов
>Может придётся создавать составные ключи, может надо будет менять саму структуру таблиц.

Вот в этом-то и нужна помощь. Для меня программирование - хобии. Я не так силен во всех тонкостях. И, честно говоря, не очень сильно понимаю принцип работы самих индексов. Поэтому, собственно, и прошут здесь помощи, т.е. каких-то конкретных советов, что поментяь местами, что добавить, что убавить, или еще что, чтобы работало быстрей.

  Ответить  
 
 автор: Косорылый   (22.12.2010 в 21:14)   письмо автору
 
   для: tAleks   (22.12.2010 в 20:44)
 

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

В этом и заключается мастерство грамотного проектирования структуры

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

Инструмент анализа вы уже знаете

Может придётся создавать составные ключи, может надо будет менять саму структуру таблиц.

  Ответить  
 
 автор: tAleks   (22.12.2010 в 20:44)   письмо автору
 
   для: Trianon   (22.12.2010 в 20:12)
 

>Структуру БД представляет себе только автор.
>Врядли кто еще сможет подсказать так в лоб.

users

CREATE TABLE users(
  id_user INT(11) NOT NULL AUTO_INCREMENT,
  sid_user INT(11) NOT NULL DEFAULT 0,
  pid_user INT(11) NOT NULL DEFAULT 0,
  id_certificate INT(11) NOT NULL DEFAULT 0,
  surname VARCHAR(50) NOT NULL,
  name VARCHAR(50) NOT NULL,
  patronymic VARCHAR(50) NOT NULL,
  user_type ENUM('customer', 'partner', 'ds', 'student') NOT NULL DEFAULT 'customer',
  customer_state ENUM('1', '2', '3', '4', '5', '6') NOT NULL,
  customer ENUM('1', '0') NOT NULL DEFAULT '0',
  student ENUM('0', '1') NOT NULL DEFAULT '0',
  partner ENUM('1', '0') NOT NULL DEFAULT '0',
  ds ENUM('1', '0') NOT NULL DEFAULT '0'
  PRIMARY KEY (id_user),
  INDEX email (email),
  INDEX id_certificate (id_certificate),
  INDEX pid_user (pid_user),
  INDEX sid_user (sid_user)
)
ENGINE = MYISAM
AUTO_INCREMENT = 1135
CHARACTER SET cp1251
COLLATE cp1251_general_ci;


certificates

CREATE TABLE certificates(
  id_certificate INT(11) NOT NULL AUTO_INCREMENT,
  id_user INT(11) NOT NULL DEFAULT 0,
  code CHAR(6) NOT NULL,
  state ENUM('new', 'actuated', 'used', 'send', 'exp') NOT NULL DEFAULT 'new',
  amount INT(11) NOT NULL,
  date_create DATE DEFAULT NULL,
  date_exp DATE DEFAULT NULL,
  type ENUM('default', 'newyear', 'birthday', '8mar', '23feb') DEFAULT 'default',
  reminder_date DATE DEFAULT NULL,
  note VARCHAR(255) NOT NULL,
  PRIMARY KEY (id_certificate),
  INDEX amount (amount),
  INDEX id_user (id_user)
)
ENGINE = MYISAM
AUTO_INCREMENT = 4461
CHARACTER SET cp1251
COLLATE cp1251_general_ci;


Если это поможет, и кто-то подскажет, что конкретно можно сделать, чтобы ускорить запрос, буду очень благодарен.

  Ответить  
 
 автор: Trianon   (22.12.2010 в 20:12)   письмо автору
 
   для: tAleks   (22.12.2010 в 19:58)
 

>>как бы заполнение таблиц сильно отличается. Нет?
>Что имеется ввиду? Не понял.
на хостинге и на локальной машине.
Вы же спрашиваете, почему эксплейны разные?
Потому что таблицы по разному заполнены.


>>А аналогичный запрос по-другому идет?
>Тоже не понял, какой аналогичный запрос?
В самом первом посте ваша фраза:
>>>>Почему считаю что медленно? Потому что есть еще аналогичны запрос:


>>Ключ users.id_certificate непервичный и неуникальный - это явное отличие.
>Да, не первичный, и не уникальный.
А user_id в users "аналогичного запроса" был первичным и уникальным.
Наверное оптимизатор SQL этим фактом воспользовался.

>>Если Вы лишь хотите знать "почему не как тот".
>Первое, что меня интересует - Как ускорить? Что сделать, чтобы быстрей работал?
Структуру БД представляет себе только автор.
Врядли кто еще сможет подсказать так в лоб.

Вообще, вопрос "как ускорить" задается вторым. Первым - "почему медленно работает".
Эксплейн Вам показал почему. Потому что индексами серверу не воспользоваться.
Вы соединяете таблицы так, что прямого единственного пути из некоторой записи одной таблицы в строго одну конкретную запись другой таблицы через её индекс нет. В результате копится дикое количество строк, которое потом перед вырезкой LIMIT приходится выгружать в файл и сортировать файлсортом. Это тяжело и медленно.

  Ответить  
 
 автор: tAleks   (22.12.2010 в 19:58)   письмо автору
 
   для: Trianon   (22.12.2010 в 18:22)
 

>как бы заполнение таблиц сильно отличается. Нет?

Что имеется ввиду? Не понял.

>А аналогичный запрос по-другому идет?

Тоже не понял, какой аналогичный запрос? Как по другому?

>Ключ users.id_certificate непервичный и неуникальный - это явное отличие.

Да, не первичный, и не уникальный.
Явное отличие от чего? В обоих вышеприведенных случаях, и на сервере и на локальной машине users.id_certificate непервичный и неуникальный. Но на локальной машине, все работает быстрей, и EXPLAIN говорит что на локальной машине индекс id_certificate используется. А на хостинге он, почему-то игнорируется.

>Если Вы лишь хотите знать "почему не как тот".

Первое, что меня интересует - Как ускорить? Что сделать, чтобы быстрей работал на хостинге?

  Ответить  
 
 автор: Trianon   (22.12.2010 в 18:22)   письмо автору
 
   для: tAleks   (22.12.2010 в 18:11)
 

как бы заполнение таблиц сильно отличается. Нет?
И на обеих машинах зрезультат запроса в конечном итоге приходится сортировать после выполнения отдельным процессом внешней сортировки.
А аналогичный запрос по-другому идет?
Ключ users.id_certificate непервичный и неуникальный - это явное отличие.
Если Вы лишь хотите знать "почему не как тот".

  Ответить  
 
 автор: tAleks   (22.12.2010 в 18:11)   письмо автору
 
   для: косорылый   (22.12.2010 в 13:43)
 

Почитал про EXPLAIN в интернете: http://www.mysql.ru/docs/man/EXPLAIN.html

В моем случае эта конструкция выдает следующее:

На хостинге:

id   select_type   table         type     possible_keys  key     key_len   ref                  rows   Extra
1    SIMPLE        certificates  ALL      NULL           NULL    NULL      NULL                 967    Using temporary; Using filesort
1    SIMPLE        users         ALL      id_certificate NULL    NULL      NULL                 1056
1    SIMPLE        o_users       eq_ref   PRIMARY        PRIMARY 4         certificates.id_user 1


На локальной машине:

id   select_type   table         type     possible_keys  key            key_len ref                         rows  Extra 
1    SIMPLE        certificates  ALL      NULL           NULL           NULL    NULL                        4407  Using filesort 
1    SIMPLE        users         ref      id_certificate id_certificate 4       certificates.id_certificate 258  
1    SIMPLE        o_users       eq_ref   PRIMARY        PRIMARY        4       certificates.id_user        1

  Ответить  
 
 автор: tAleks   (22.12.2010 в 17:17)   письмо автору
 
   для: Trianon   (22.12.2010 в 16:56)
 

Да, спасибо что пояснили. Теперь понял. Получается что в моем запросе, нет необходимости в GROUP BY. Убрал его, но все равно запрос выполняется медленно.


<?php 
$sql 

  SELECT 
    certificates.*, 
    certificates.id_user AS oid_user, 
    users.id_user AS id_user, 
    users.user_type AS u_user_type, 
    o_users.sid_user AS o_sid_user, 
    o_users.user_type AS o_user_type, 
    TRIM(CONCAT_WS(' ', users.surname, users.name, users.patronymic)) AS u_name, 
    TRIM(CONCAT_WS(' ', o_users.surname, o_users.name, o_users.patronymic)) AS o_name 
  FROM certificates 
  LEFT JOIN users USING(id_certificate) 
  LEFT JOIN users AS o_users ON o_users.id_user = certificates.id_user 
  ORDER BY 
$order IS NULL OR $order = '' $sort$order $sort 
  LIMIT 
$start$numrec"
?> 

  Ответить  

Сообщения:  [1-10]   [11-18] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

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