Mysql: ограничение „UNIQUE“ над голям низ

Какъв може да е възможният недостатък от наличието на ограничение UNIQUE за голям низ (varchar) (приблизително 100 знака или така) в MYSQL по време на:

  • вмъкнете фаза
  • фаза на извличане (на друг първичен ключ)

Може ли дължината на заявката да повлияе на производителността на четене/запис? (Освен използването на диск/памет за счетоводство).

Благодаря


person Harshit    schedule 15.03.2019    source източник


Отговори (1)


Няколко въпроса. Има ограничение за размера на колона в индекс (191, 255, 767, 3072 и т.н., в зависимост от различни неща).

Вашата колона се побира в ограничението.

Просто направете ключ UNIQUE или PRIMARY за тази колона. Има малки проблеми с производителността, но имайте това предвид: Извличането на ред е по-скъпо от всякакви проблеми с типа данни, включващи ключа, използван за намирането му.

Колоната ви няма да се побере.

Сега заобиколните решения стават грозни.

  • Префиксът на индекс (INDEX foo(50)) има редица проблеми и неефективност.
  • UNIQUE foo(50) е абсолютно грешно. Той декларира, че първите 50 знака са ограничени да бъдат уникални, не цялата колона.
  • Заобиколните решения с хеширане на низа (cf md5, sha1 и т.н.) имат редица проблеми и неефективност. Все пак това може да е единственият жизнеспособен начин за налагане на уникалност на дълъг низ.

(Ще допълня, ако е необходимо.)

Извличане на ред (Ако приемем, че операторът е анализиран и PRIMARY KEY е наличен.)

  1. Разбийте BTree, съдържащо данните (и подредено от PK). Това може да включва пренасяне на блок (или повече) от диска в buffer_pool.
  2. Анализирайте блока, за да намерите реда. (В блока вероятно има десетки редове.)
  3. В даден момент от процеса заключете реда за четене и/или бъдете блокирани от друга връзка, която е, да речем, актуализиране или изтриване.
  4. Разделете реда, т.е. разделете го на колони.
  5. За всички необходими колони с текст/петна посегнете към хранилището без запис. (Широките колони не се съхраняват с малките елементи на реда; те се съхраняват в друг блок(ове).)
  6. Преобразувайте от вътрешното хранилище (не подравнено по думи, little-endian и т.н.) в желания формат. (Малко количество CPU код, но необходимо.)

Ако следващата стъпка е да сравните два низа (за JOIN или ORDER BY), това е просто извикване на подпрограма за сканиране на колкото и символи да има. (Добре, повечето utf8 съпоставки не са „прости“.) И, да, сравняването на два INT би било по-бързо.

person Rick James    schedule 15.03.2019
comment
Можете ли да разясните по-подробно „Извличането на ред е по-скъпо от всякакви проблеми с типа данни, включващи ключа, използван за намирането му.“ - person Harshit; 16.03.2019
comment
@RickJames, можеш ли да обясниш малко за това For any text/blob columns needed, reach into the off-record storage и Convert from the internal storage into desired format - person swayamraina; 01.06.2019