На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается для обсуждения вопросов использования баз данных, за исключением составления запросов на SQL. Для этого выделен специальный раздел. Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Chow, Bas, MIF
  
> правильный выбор индексов mysql
    Есть вот такая таблица в бд:
    ExpandedWrap disabled
      CREATE TABLE `table` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `data` varchar(50) NOT NULL,
        `counter` smallint(5) unsigned NOT NULL DEFAULT '0',
        `flag1` smallint(5) unsigned NOT NULL DEFAULT '0',
        `flag2` smallint(5) unsigned NOT NULL DEFAULT '0',
        `knock` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (`id`)
      )

    В ней 300к строк. Происходит 2 вида запросов:
    ExpandedWrap disabled
      1) UPDATE ... WHERE `id` IN (...)
      2) SELECT `id`, `data` FROM `table` WHERE `counter`<300 AND `flag1`<3 AND `flag2`<3 AND `knock`<NOW()-INTERVAL 60 SECOND LIMIT 100

    С первым запросом проблем нет, `id` является PRIMARY.
    Я довольно долго пытался оптимизировать второй запрос, пока случайно не обнаружил, что вначале запросы выполняются быстро, а потом по мере заполнения таблицы дольше (так как найти строки подходящие под условие становится все тяжелее). И тут я понял, что главное - это индексы. А у меня на колонки из WHERE индексов нет. (я заметил, что сейчас время ответа колеблется от 0.04s до 0.9s в зависимости от заполненности таблицы).
    Я прочитал теорию: про составные индексы, про проверку с помощью EXPLAIN. Но у меня не выходит правильно оптимизировать. EXPLAIN почти все время показывает, что ему потребовалось просмотреть все 300к строк, и key=NULL, а possible_key не равен NULL.
    Прошу помочь.
    Условия такие: никакое из полей не UNIQUE. counter может принимать значения от 0 до 300, flag1 и flag2 от 0 до 3, knock любой timestamp примерно за последние сутки.
    И еще вопрос - для индексов не имеет значения тип таблицы? MEMORY или MyIsam - должно же быть все равно?

    UPD:
    Например, если просто задать INDEX по полю `counter`, то
    EXPLAIN SELECT `id` FROM `table` WHERE `counter`=30 - ключ используется
    EXPLAIN SELECT `id` FROM `table` WHERE `counter` BETWEEN 29 AND 31 - ключ не используется
    почему так?
    Сообщение отредактировано: Dart_Sitius -
      Если не ошибаюсь Вам нужен BTREE INDEX
        grgdvo, спасибо за ответ. в mysql у меня по умолчанию задается btree, а не hash. но кажется я понял, что дело в cardinality

        UPD: оказывается по умолчанию совсем не BTREE (не знаю как так проглядел), btree действительно помог, спасибо
        Сообщение отредактировано: Dart_Sitius -
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0183 ]   [ 15 queries used ]   [ Generated: 27.04.24, 03:06 GMT ]