За последние 24 часа нас посетили 21753 программиста и 1689 роботов. Сейчас ищут 1982 программиста ...

Индексы по varchar

Тема в разделе "MySQL", создана пользователем Алекс8, 17 июл 2017.

  1. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    Ребята, у меня вопрос.
    Есть столбец item (varchar(10)) в ut8mb4 табличке (innoDb)..
    записей в таблице может быть много, реально сотни тысяч
    но разных значений в этом столбце максимально может быть 5-6..
    делаю по этому полю индекс... если допустим индекс будет не на 10 символов, а на 3...это ускорит поиск или пофиг 10 или 3??

    и может лучше использоваться связь "один ко многим"? одна табличка с значениями и автоинкрементным столбцом.. а вторая табличка просто ид этих значения..
    ну и плюс связать может эти таблички foreign ключами?

    что будет более производительно??
    --- Добавлено ---
    хотя пока писал понял что наверно один ко многим будет лучше.. и индексы меньше занимать будут и табличка сама будет меньше занимать.. плюс внешние ключи тоже могут облегчить жизнь..
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    тебя чем-то не устраивает текущая производительность?
     
  3. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    когда записей за миллион, приходится историю чистить)) начинает чуть чуть тупить.. в медленных запросах мускула видно..
    это больше для меня сейчас гипотетический вопрос чем практический)) на практике я раз в полгода чищу просто таблицу от старых записей)
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    не должно тупить
    давай структуру и индексы покаж
    и запрос
     
  5. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    PHP:
    1. CREATE TABLE IF NOT EXISTS `smf_kpr_grades` (
    2.   `id` int(10) NOT NULL AUTO_INCREMENT,
    3.   `item` varchar(10) NOT NULL DEFAULT 'message',
    4.   `item_id` int(10) NOT NULL,
    5.   `grade` int(10) NOT NULL,
    6.   `grade_author` int(10) NOT NULL,
    7.   `grade_time` int(10) NOT NULL,
    8.   PRIMARY KEY (`id`),
    9.   KEY `idx_item_and_item_id_and_author` (`item`,`item_id`,`grade_author`),
    10.   KEY `grade_time` (`grade_time`)
    11. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=25090364 ;
    а запрос или это
    PHP:
    1.     $request = $smcFunc['db_query']('', '
    2.        SELECT k.grade, k.grade_author, IFNULL(mem.real_name, 0) AS grader, mg.online_color
    3.        FROM {db_prefix}kpr_grades AS k
    4.            LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = k.grade_author)
    5.            LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = mem.id_group)
    6.        WHERE k.item = {string:type}
    7.            AND k.item_id = {int:id}
    8.        ORDER BY k.grade_time',
    9.         array(
    10.             'type' => 'message',
    11.             'id'   => $itemID,
    12.         )
    13.     );
    или этот
    PHP:
    1.     $request = $smcFunc['db_query']('', '
    2.        SELECT m.id_msg, k.grade
    3.        FROM {db_prefix}messages AS m
    4.            LEFT JOIN {db_prefix}kpr_grades AS k ON (k.item_id = m.id_msg AND k.item = {string:type})
    5.        WHERE k.item = {string:type}
    6.            AND k.item_id BETWEEN {int:first} AND {int:last}
    7.            AND k.grade_author = {int:user}
    8.            AND m.id_topic = {int:topic}',
    9.         array(
    10.             'type'  => 'message',
    11.             'topic' => $context['current_topic'],
    12.             'first' => $context['first_message'], // id первого сообщения на текущей странице темы
    13.             'last'  => $context['topic_last_message'],
    14.             'user'  => $context['user']['id'],
    15.         )
    16.     );
    на данный момент таблица не сильно забита и поэтому не могу сказать точно..

    П.С. Да ошибся.. табличка не в innoDB а MyISAM
     
  6. t1grok

    t1grok Новичок

    С нами с:
    29 янв 2017
    Сообщения:
    119
    Симпатии:
    32
    В первую очередь выбросить этого динозавра.

    А точно ли item дает лучшую селективность, чем item_id? Если нет, то поменять местами.
    И вообще, возможно будет лучше создать несколько индексов, нужно пробовать и смотреть план выполнения запроса.
     
  7. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    первый запрос должен работать быстро. если работает медленно, то смотри, чтобы были индексы. Его можно сделать без джоинов, а зависмые сущности выбрать после по собранным ключам.

    второй запрос можно денормализовать. за каким хреном вообще грейд сообщения хранится в другой таблице?
     
  8. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    не знаю.. это чужой скрипт))
     
  9. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    где результат выполнения explain