sql >> Database >  >> RDS >> Mysql

#1071 - Opgegeven sleutel was te lang; maximale sleutellengte is 1000 bytes

Zoals @Devart zegt, is de totale lengte van je index te lang.

Het korte antwoord is dat je zulke lange VARCHAR-kolommen sowieso niet zou moeten indexeren, omdat de index erg omvangrijk en inefficiënt zal zijn.

Het beste is om prefix-indexen te gebruiken dus je indexeert alleen een linker substring van de gegevens. De meeste van je gegevens zullen sowieso een stuk korter zijn dan 255 tekens.

U kunt een prefixlengte per kolom declareren terwijl u de index definieert. Bijvoorbeeld:

...
KEY `index` (`parent_menu_id`,`menu_link`(50),`plugin`(50),`alias`(50))
...

Maar wat is de beste prefixlengte voor een bepaalde kolom? Hier is een methode om erachter te komen:

SELECT
 ROUND(SUM(LENGTH(`menu_link`)<10)*100/COUNT(`menu_link`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`menu_link`)<20)*100/COUNT(`menu_link`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`menu_link`)<50)*100/COUNT(`menu_link`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`menu_link`)<100)*100/COUNT(`menu_link`),2) AS pct_length_100
FROM `pds_core_menu_items`;

Het vertelt je het aantal rijen dat niet meer dan een bepaalde tekenreekslengte heeft in de menu_link kolom. Mogelijk ziet u de uitvoer als volgt:

+---------------+---------------+---------------+----------------+
| pct_length_10 | pct_length_20 | pct_length_50 | pct_length_100 |
+---------------+---------------+---------------+----------------+
|         21.78 |         80.20 |        100.00 |         100.00 |
+---------------+---------------+---------------+----------------+

Dit vertelt u dat 80% van uw tekenreeksen minder dan 20 tekens bevatten en dat al uw tekenreeksen minder dan 50 tekens bevatten. Het is dus niet nodig om meer dan een prefixlengte van 50 te indexeren, en zeker niet om de volledige lengte van 255 tekens te indexeren.

PS:De INT(1) en INT(32) datatypes wijst op een ander misverstand over MySQL. Het numerieke argument heeft geen invloed op de opslag of het bereik van de toegestane waarden voor de kolom. INT is altijd 4 bytes en staat altijd waarden van -2147483648 tot 2147483647 toe. Het numerieke argument gaat over opvulwaarden tijdens de weergave, wat geen effect heeft tenzij u de ZEROFILL gebruikt optie.



  1. Bereken deciel in MySQL op basis van totalen

  2. Hoe Random() werkt in PostgreSQL

  3. Waarom kan ik geen aggregatiefunctie uitvoeren op een expressie die een aggregatie bevat, maar wel door er een nieuwe select-instructie omheen te maken?

  4. Hoe MySQL Workbench op Ubuntu te installeren?