sql >> Database >  >> RDS >> Mysql

Verborgen functies van MySQL

Aangezien je een premie hebt betaald, zal ik mijn zwaarbevochten geheimen delen...

Over het algemeen moesten alle SQL's die ik vandaag heb aangepast, subquery's gebruiken. Omdat ik uit de Oracle-databasewereld kwam, werkten dingen die ik als vanzelfsprekend beschouwde niet hetzelfde met MySQL. En mijn lezing over MySQL-tuning doet me concluderen dat MySQL achter Oracle staat als het gaat om het optimaliseren van query's.

Hoewel de eenvoudige query's die voor de meeste B2C-applicaties nodig zijn, goed kunnen werken voor MySQL, lijken de meeste van het geaggregeerde rapportagetype van query's die nodig zijn voor Intelligence Reporting nogal wat planning en reorganisatie van de SQL-query's te vereisen om MySQL te begeleiden om ze sneller uit te voeren.

Beheer:

max_connections is het aantal gelijktijdige verbindingen. De standaardwaarde is 100 verbindingen (151 sinds 5.0) - erg klein.

Opmerking:

verbindingen nemen geheugen in beslag en uw besturingssysteem kan mogelijk niet veel verbindingen aan.

Met MySQL-binaire bestanden voor Linux/x86 kunt u tot 4096 gelijktijdige verbindingen hebben, maar zelfgecompileerde binaire bestanden hebben vaak minder een limiet.

Stel table_cache in om overeen te komen met het aantal openstaande tabellen en gelijktijdige verbindingen. Bekijk de waarde van open_tables en als deze snel groeit, moet u de waarde vergroten.

Opmerking:

De 2 vorige parameters kunnen veel open bestanden vereisen. 20+max_connections+table_cache*2 is een goede schatting voor wat je nodig hebt. MySQL op Linux heeft een open_file_limit optie, stel deze limiet in.

Als u complexe query's heeft, zijn sort_buffer_size en tmp_table_size waarschijnlijk erg belangrijk. Waarden zijn afhankelijk van de complexiteit van de zoekopdracht en de beschikbare bronnen, maar respectievelijk 4 MB en 32 MB zijn aanbevolen startpunten.

Opmerking:dit zijn "per verbinding"-waarden, waaronder read_buffer_size, read_rnd_buffer_size en enkele andere, wat betekent dat deze waarde voor elke verbinding nodig kan zijn. Houd dus rekening met uw belasting en beschikbare resource bij het instellen van deze parameters. Sort_buffer_size wordt bijvoorbeeld alleen toegewezen als MySQL een sortering moet doen. Opmerking:pas op dat het geheugen niet vol raakt.

Als u veel verbindingen tot stand heeft gebracht (d.w.z. een website zonder permanente verbindingen), kunt u de prestaties verbeteren door thread_cache_size in te stellen op een waarde die niet nul is. 16 is een goede waarde om mee te beginnen. Verhoog de waarde totdat uw threads_created niet erg snel groeien.

PRIMAIRE SLEUTEL:

Er kan slechts één AUTO_INCREMENT-kolom per tabel zijn, deze moet worden geïndexeerd en mag geen DEFAULT-waarde hebben

KEY is normaal gesproken een synoniem voor INDEX. Het sleutelattribuut PRIMARY KEY kan ook worden opgegeven als alleen KEY wanneer het wordt opgegeven in een kolomdefinitie. Dit is geïmplementeerd voor compatibiliteit met andere databasesystemen.

EEN PRIMAIRE SLEUTEL is een unieke index waarbij alle sleutelkolommen moeten worden gedefinieerd als NIET NULL

Als een PRIMARY KEY- of UNIQUE-index uit slechts één kolom met een geheel getal bestaat, kunt u in SELECT-instructies ook naar de kolom verwijzen als "_rowid".

In MySQL is de naam van een PRIMAIRE SLEUTEL PRIMAIRE

Momenteel ondersteunen alleen InnoDB (v5.1?) tabellen externe sleutels.

Gewoonlijk maakt u alle indexen die u nodig hebt wanneer u tabellen maakt. Elke kolom die is gedeclareerd als PRIMARY KEY, KEY, UNIQUE of INDEX wordt geïndexeerd.

NULL betekent "geen waarde hebben". Als u op NULL wilt testen, kunt u niet gebruik de rekenkundige vergelijkingsoperatoren zoals =, . Gebruik in plaats daarvan de operators IS NULL en IS NOT NULL:

NO_AUTO_VALUE_ON_ZERO onderdrukt automatische verhoging voor 0, zodat alleen NULL het volgende volgnummer genereert. Deze modus kan handig zijn als 0 is opgeslagen in de AUTO_INCREMENT-kolom van een tabel. (Het opslaan van 0 wordt trouwens niet aanbevolen.)

Om de waarde te wijzigen van de AUTO_INCREMENT-teller die voor nieuwe rijen moet worden gebruikt:

ALTER TABLE mytable AUTO_INCREMENT = value; 

ofSET INSERT_ID =waarde;

Tenzij anders aangegeven, begint de waarde met:1000000 of specificeer het als volgt:

...) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1

TIJDSSTEMPELS:

Waarden voor TIMESTAMP-kolommen worden geconverteerd van de huidige tijdzone naar UTC voor opslag en van UTC naar de huidige tijdzone om ze op te halen.

http://dev.mysql.com/doc/refman/5.1 /en/timestamp.html Voor één TIMESTAMP-kolom in een tabel kunt u de huidige tijdstempel toewijzen als de standaardwaarde en de waarde voor automatisch bijwerken.

één ding om op te letten bij het gebruik van een van deze typen in een WHERE-clausule, is het het beste om te doenWHERE datecolumn =FROM_UNIXTIME (1057941242) en notWHERE UNIX_TIMESTAMP(datecolumn) =1057941242. Als u dit laatste doet, profiteert u niet van een index daarop kolom.

http://dev.mysql.com /doc/refman/5.1/en/date-and-time-functions.html

 UNIX_TIMESTAMP() 
 FROM_UNIXTIME() 
 UTC_DATE()
 UTC_TIME()
 UTC_TIMESTAMP()

als je een datetime converteert naar een unix timestamp in MySQL:
En dan 24 uur erbij optelt:
En dan terug converteert naar een datetime, dan verliest het op magische wijze een uur!

Dit is wat er gebeurt. Bij het terug converteren van de unix timestamp naar een datetime wordt rekening gehouden met de tijdzone en het toeval wil dat we tussen 28 en 29 oktober 2006 de zomertijd verlieten en een uur verloren.

Vanaf MySQL 4.1.3 retourneren de functies CURRENT_TIMESTAMP(), CURRENT_TIME(), CURRENT_DATE() en FROM_UNIXTIME() waarden in de huidige tijdzone van de verbinding , die beschikbaar is als de waarde van de systeemvariabele time_zone. Bovendien gaat UNIX_TIMESTAMP() ervan uit dat het argument een datetime-waarde in de huidige tijdzone is.

De huidige tijdzone-instelling heeft geen invloed op waarden die worden weergegeven door functies zoals UTC_TIMESTAMP() of waarden in DATE-, TIME- of DATETIME-kolommen.

OPMERKING:BIJ UPDATE ALLEEN werkt de DateTime bij als een veld wordt gewijzigd. Als een UPDATE ertoe leidt dat er geen velden worden gewijzigd, wordt de DateTime NIET bijgewerkt!

Bovendien is de Eerste TIMESTAMP altijd standaard AUTOUPDATE, zelfs als deze niet is opgegeven

Als ik met datums werk, verwijs ik bijna altijd naar de Juliaanse datum, omdat gegevenswiskunde dan een kwestie is van het optellen of aftrekken van gehele getallen, en seconden sinds middernacht om dezelfde reden. Het komt zelden voor dat ik tijd nodig heb met een fijnere granulariteit dan seconden.

Beide kunnen worden opgeslagen als een geheel getal van 4 bytes, en als de ruimte erg krap is, kunnen ze worden gecombineerd in UNIX-tijd (seconden sinds het tijdperk 1/1/1970) als een geheel getal zonder teken dat goed zal zijn tot ongeveer 2106 als:

' seconden in 24 uur =86400

' Getekend geheel getal max val =2.147.483.647 - kan 68 jaar seconden bevatten

' Niet-ondertekend geheel getal max val =4.294.967.295 - kan 136 jaar seconden bevatten

Binair protocol:

MySQL 4.1 heeft een binair protocol geïntroduceerd waarmee niet-stringgegevenswaarden kunnen worden verzonden en geretourneerd in native formaat zonder conversie van en naar stringformaat. (Zeer handig)

Afgezien daarvan is mysql_real_query() sneller dan mysql_query() omdat het strlen() niet aanroept om op de instructiereeks te werken.

http://dev.mysql.com/tech-resources /articles/4.1/prepared-statements.html Het binaire protocol ondersteunt door de server opgestelde verklaringen en maakt verzending van gegevenswaarden in native formaat mogelijk. Het binaire protocol onderging nogal wat herziening tijdens de eerdere releases van MySQL 4.1.

U kunt de macro IS_NUM() gebruiken om te testen of een veld een numeriek type heeft. Geef de typewaarde door aan IS_NUM() en het evalueert naar TRUE als het veld numeriek is:

Een ding om op te merken is dat binaire gegevens KAN worden verzonden in een gewone zoekopdracht als u eraan ontsnapt en onthoud dat MySQL alleen . nodig heeft die backslash en het aanhalingsteken moeten een escapeteken zijn. Dat is dus een heel gemakkelijke manier om kortere binaire strings in te voegen, zoals versleutelde/gezouten wachtwoorden.

Hoofdserver:

http://www.experts-exchange.com/Database/MySQL/Q_22967482 .html

http://www.databasejournal.com/features/mysql/article.php /10897_3355201_2

SUBSIDIE REPLICATIESLAVE OP . naar slave_user GEDENTIFICEERD DOOR 'slave_password'

#Master Binary Logging Config  STATEMENT causes replication 
              to be statement-based -  default

log-bin=Mike
binlog-format=STATEMENT
server-id=1            
max_binlog_size = 10M
expire_logs_days = 120    


#Slave Config
master-host=master-hostname
master-user=slave-user
master-password=slave-password
server-id=2

Binair logbestand moet lezen:

http://dev.mysql.com/doc/refman /5.0/en/binary-log.html

http://www.mydigitallife.info/2007/10/06/how-to-read-mysql-binary-log-files-binlog-with-mysqlbinlog/

http://dev.mysql.com/doc/refman/5.1 /en/mysqlbinlog.html

http://dev.mysql.com/doc/refman /5.0/en/binary-log.html

http://dev.mysql.com/doc /refman/5.1/en/binary-log-setting.html

U kunt alle binaire logbestanden verwijderen met de RESET MASTER-instructie, of een subset ervan met PURGE MASTER

--result-file=binlog.txt TrustedFriend-bin.000030

Normalisatie:

http://dev.mysql.com/tech-resources /articles/intro-to-normalization.html

UDF-functies

http://www.koders.com/cpp/fid10666379322B54AD41AEB0E4100D87C8.as

http://souptonuts.sourceforge.net/readme_mysql.htm

Gegevenstypen:

http://dev.mysql.com/doc/refman /5.1/en/storage-requirements.html

http://www.informit.com/articles/article.aspx ?p=1238838&seqNum=2

http://bitfilm. net/2008/03/24/saving-bytes-efficient-data-storage-mysql-part-1/

Een ding om op te merken is dat op een gemengde tafel met zowel CHAR als VARCHAR, mySQL de CHAR's zal veranderen in VARCHAR's

RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMAIRE SLEUTEL (RecNum)

MySQL vertegenwoordigt altijd datums met het jaar eerst, in overeenstemming met de standaard SQL- en ISO 8601-specificaties

Diversen:

Het uitschakelen van sommige MySQl-functionaliteit resulteert in kleinere gegevensbestanden en snellere toegang. Bijvoorbeeld:

--datadir zal de gegevensmap specificeren en

--skip-innodb schakelt de inno-optie uit en bespaart u 10-20M

Meer hierhttp://dev.mysql.com/tech -resources/articles/mysql-c-api.html

Download Hoofdstuk 7 - Gratis

InnoDB is transactioneel, maar er is een prestatieoverhead die daarmee gepaard gaat. Ik heb gemerkt dat MyISAM-tabellen voldoende zijn voor 90% van mijn projecten. Niet-transactieveilige tabellen (MyISAM) hebben verschillende eigen voordelen, die allemaal voorkomen omdat:

er is geen transactieoverhead:

Veel sneller

Lagere schijfruimtevereisten

Minder geheugen nodig om updates uit te voeren

Elke MyISAM-tabel wordt in drie bestanden op schijf opgeslagen. De bestanden hebben namen die beginnen met de tabelnaam en hebben een extensie om het bestandstype aan te geven. Een .frm-bestand slaat het tabelformaat op. Het gegevensbestand heeft de extensie .MYD (MYData). Het indexbestand heeft de extensie .MYI (MYIndex).

Deze bestanden kunnen worden gekopieerd naar een intacte opslaglocatie zonder de back-upfunctie van MySQL Administrators te gebruiken, wat tijdrovend is (net als het terugzetten)

De truc is om een ​​kopie van deze bestanden te maken en vervolgens de tabel te DROPPEN. Wanneer u de bestanden terugzet, zal MySQl ze herkennen en de tabeltracking bijwerken.

Als u een back-up/herstel moet maken,

Het herstellen van een back-up of het importeren van een bestaand dumpbestand kan lang duren, afhankelijk van het aantal indexen en primaire sleutels dat u op elke tabel hebt. U kunt dit proces aanzienlijk versnellen door uw originele dumpbestand aan te passen door het te omringen met het volgende:

SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;

.. your dump file ..

SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;

Om de snelheid van het herladen enorm te verhogen, voegt u het SQL-commando SET AUTOCOMMIT =0 toe; aan het begin van het dumpbestand en voeg de COMMIT; opdracht tot het einde.

Standaard is autocommit aan, wat betekent dat elke invoegopdracht in het dumpbestand als een afzonderlijke transactie wordt behandeld en naar de schijf wordt geschreven voordat de volgende wordt gestart. Als u deze opdrachten niet toevoegt, kan het herladen van een grote database in InnoDB vele uren duren...

De maximale grootte van een rij in een MySQL-tabel is 65.535 bytes

De effectieve maximale lengte van een VARCHAR in MySQL 5.0.3 en verder =maximale rijgrootte (65.535 bytes)

VARCHAR-waarden worden niet opgevuld wanneer ze worden opgeslagen. Naloopspaties blijven behouden wanneer waarden worden opgeslagen en opgehaald, in overeenstemming met standaard SQL.

CHAR- en VARCHAR-waarden in MySQL worden vergeleken zonder rekening te houden met volgspaties.

Het gebruik van CHAR zal uw toegang alleen versnellen als het hele record een vaste grootte heeft. Dat wil zeggen, als je een object met variabele grootte gebruikt, kun je ze net zo goed allemaal van variabele grootte maken. Je wint geen snelheid door een CHAR te gebruiken in een tabel die ook een VARCHAR bevat.

De VARCHAR-limiet van 255 tekens is verhoogd tot 65535 tekens vanaf MySQL 5.0.3

Zoeken in volledige tekst wordt alleen ondersteund voor MyISAM-tabellen.

http://dev.mysql.com/doc/refman /5.0/en/fulltext-search.html

BLOB-kolommen hebben geen tekenset en sorteren en vergelijken zijn gebaseerd op de numerieke waarden van de bytes in kolomwaarden

Als de strikte SQL-modus niet is ingeschakeld en u een waarde toewijst aan een BLOB- of TEXT-kolom die de maximale lengte van de kolom overschrijdt, wordt de waarde afgekapt om te passen en wordt er een waarschuwing gegenereerd.

Handige opdrachten:

controleer strikte modus:SELECT @@global.sql_mode;

strikte modus uitschakelen:

SET @@global.sql_mode='';

SET @@global.sql_mode='MYSQL40'

of verwijder:sql-mode="STRICT_TRANS_TABLES,...

TOON KOLOMMEN VAN mytable

SELECT max(namecount) AS virtualcolumn VANAF mytable BESTELLEN DOOR virtuele kolom

http://dev.mysql.com /doc/refman/5.0/en/group-by-hidden-fields.html

http://dev.mysql .com/doc/refman/5.1/en/information-functions.html#function_last-insert-id last_insert_id()

krijgt u de PK van de laatste rij die in de huidige thread is ingevoegd max (pkcolname) geeft u de laatste PK in het algemeen.

Opmerking:als de tabel leeg is, retourneert max(pkcolname) 1 mysql_insert_id() converteert het retourtype van de native MySQL C API-functie mysql_insert_id() naar een type oflong (int genoemd in PHP).

Als uw AUTO_INCREMENT-kolom het kolomtype BIGINT heeft, is de waarde die wordt geretourneerd doormysql_insert_id() onjuist. Gebruik in plaats daarvan de interne MySQL SQL-functie LAST_INSERT_ID() in een SQL-query.

http://dev.mysql .com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

Gewoon een opmerking dat wanneer u probeert gegevens in een tabel in te voegen en u de foutmelding krijgt:

Unknown column ‘the first bit of data what you want to put into the table‘ in ‘field list’

iets gebruiken als

INSERT INTO table (this, that) VALUES ($this, $that)

het is omdat je geen apostrofs hebt rond de waarden die je in de tabel probeert te plakken. Dus je moet je code veranderen in:

INSERT INTO table (this, that) VALUES ('$this', '$that') 

herinnering dat `` wordt gebruikt om MySQL-velden, databases of tabellen te definiëren, niet waarden;)

Verbinding met server verbroken tijdens zoekopdracht:

http://dev.mysql.com/doc/refman /5.1/nl/weg-weg.html

http://dev.mysql.com/doc /refman/5.1/en/packet-too-large.html

http://dev.mysql.com/doc/refman /5.0/nl/server-parameters.html

http://dev.mysql.com/doc/refman /5.1/nl/show-variables.html

http://dev.mysql.com/doc/refman /5.1/en/option-files.html

http://dev.mysql.com/doc/refman /5.1/nl/error-log.html

Afstemmingsquery's

http://www.artfulsoftware.com/infotree/queries.php?&bw =1313

Nou, dat zou genoeg moeten zijn om de bonus te verdienen zou ik denken... De vruchten van vele uren en vele projecten met een geweldige gratis databank. Ik ontwikkel applicatiedataservers op Windows-platforms, meestal met MySQL. De ergste rotzooi die ik moest rechtzetten was

De ultieme MySQL legacy-database-nachtmerrie

Dit vereiste een reeks toepassingen om de tabellen te verwerken tot iets bruikbaars met behulp van veel van de hier genoemde trucs.

Als je dit verbazingwekkend nuttig vond, bedank dan door erop te stemmen.

Bekijk ook mijn andere artikelen en whitepapers op:www.coastrd.com



  1. Wijs hosttoegangsrechten opnieuw toe aan MySQL-gebruiker

  2. FULLTEXT-zoekopdracht in MySQL levert geen rijen op

  3. Visual Studio:ContextSwitchDeadlock

  4. Oracle (ORA-02270):geen overeenkomende unieke of primaire sleutel voor deze kolomlijstfout