sql >> Database teknologi >  >> RDS >> Mysql

Skjulte funktioner i MySQL

Siden du har afsat en dusør, deler jeg mine hårdt vundne hemmeligheder...

Generelt krævede alle de SQL'er, jeg tunede i dag, brug af underforespørgsler. Da jeg kom fra Oracles databaseverden, fungerede ting, jeg tog for givet, ikke det samme med MySQL. Og min læsning om MySQL-tuning får mig til at konkludere, at MySQL står bag Oracle med hensyn til optimering af forespørgsler.

Selvom de simple forespørgsler, der kræves til de fleste B2C-applikationer, kan fungere godt for MySQL, synes de fleste af den samlede rapporteringstype, der er nødvendig for Intelligence Reporting, at kræve en del planlægning og omorganisering af SQL-forespørgslerne for at guide MySQL til at udføre dem hurtigere.

Administration:

max_connections er antallet af samtidige forbindelser. Standardværdien er 100 forbindelser (151 siden 5.0) - meget lille.

Bemærk:

forbindelser tager hukommelse, og dit OS er muligvis ikke i stand til at håndtere mange forbindelser.

MySQL binære filer til Linux/x86 giver dig mulighed for at have op til 4096 samtidige forbindelser, men selvkompilerede binære filer har ofte mindre grænser.

Indstil table_cache til at matche antallet af dine åbne tabeller og samtidige forbindelser. Se open_tables-værdien, og hvis den vokser hurtigt, bliver du nødt til at øge dens størrelse.

Bemærk:

De 2 foregående parametre kræver muligvis mange åbne filer. 20+max_connections+table_cache*2 er et godt skøn for, hvad du har brug for. MySQL på Linux har en open_file_limit mulighed, indstil denne grænse.

Hvis du har komplekse forespørgsler, er sort_buffer_size og tmp_table_size sandsynligvis meget vigtige. Værdier vil afhænge af forespørgslens kompleksitet og tilgængelige ressourcer, men henholdsvis 4 Mb og 32 Mb er anbefalede udgangspunkter.

Bemærk:Disse er "pr. forbindelse"-værdier, blandt read_buffer_size, read_rnd_buffer_size og nogle andre, hvilket betyder, at denne værdi kan være nødvendig for hver forbindelse. Så overvej din belastning og tilgængelige ressource, når du indstiller disse parametre. For eksempel tildeles sort_buffer_size kun, hvis MySQL skal udføre en sortering. Bemærk:pas på ikke at løbe tør for hukommelse.

Hvis du har mange forbindelser etableret (dvs. et websted uden vedvarende forbindelser), kan du forbedre ydeevnen ved at indstille thread_cache_size til en værdi, der ikke er nul. 16 er god værdi at starte med. Forøg værdien, indtil dine threads_created ikke vokser særlig hurtigt.

PRIMÆR NØGLE:

Der kan kun være én AUTO_INCREMENT-kolonne pr. tabel, den skal indekseres, og den kan ikke have en DEFAULT-værdi

KEY er normalt et synonym for INDEX. Nøgleattributten PRIMARY KEY kan også angives som kun KEY, når den er angivet i en kolonnedefinition. Dette blev implementeret for kompatibilitet med andre databasesystemer.

En PRIMÆR NØGLE er et unikt indeks, hvor alle nøglekolonner skal defineres som IKKE NULL

Hvis et PRIMARY KEY eller UNIQUE indeks kun består af én kolonne, der har en heltalstype, kan du også henvise til kolonnen som "_rovid" i SELECT-sætninger.

I MySQL er navnet på en PRIMÆR NØGLE PRIMÆR

I øjeblikket understøtter kun InnoDB (v5.1?) tabeller fremmednøgler.

Normalt opretter du alle de indekser, du har brug for, når du opretter tabeller. Enhver kolonne, der er erklæret som PRIMÆR NØGLE, NØGLE, UNIK eller INDEKS, vil blive indekseret.

NULL betyder "ikke at have en værdi". For at teste for NULL kan du ikke brug de aritmetiske sammenligningsoperatorer såsom =, . Brug operatorerne IS NULL og IS NOT NULL i stedet:

NO_AUTO_VALUE_ON_ZERO undertrykker automatisk stigning for 0, så kun NULL genererer det næste sekvensnummer. Denne tilstand kan være nyttig, hvis 0 er blevet gemt i en tabels AUTO_INCREMENT-kolonne. (At gemme 0 er i øvrigt ikke en anbefalet praksis.)

For at ændre værdien af ​​AUTO_INCREMENT-tælleren, der skal bruges til nye rækker:

ALTER TABLE mytable AUTO_INCREMENT = value; 

ellerSET INSERT_ID =værdi;

Medmindre andet er angivet, vil værdien begynde med:1000000 eller angive den således:

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

TIDSSTEMPLER:

Værdier for TIMESTAMP-kolonner konverteres fra den aktuelle tidszone til UTC til lagring og fra UTC til den aktuelle tidszone til hentning.

http://dev.mysql.com/doc/refman/5.1 /da/timestamp.html For én TIMESTAMP-kolonne i en tabel kan du tildele det aktuelle tidsstempel som standardværdien og den automatiske opdateringsværdi.

én ting at være opmærksom på, når du bruger en af ​​disse typer i en WHERE-sætning, er det bedst at doWHERE datecolumn =FROM_UNIXTIME(1057941242) og notWHERE UNIX_TIMESTAMP(datecolumn) =1057941242. at gøre sidstnævnte vil ikke drage fordel af et indeks på det kolonne.

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

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

hvis du konverterer et datetime til et unix-tidsstempel i MySQL:
Og tilføjer 24 timer til det:
Og konverterer det så tilbage til et datetime, mister det på magisk vis en time!

Her er hvad der sker. Når man konverterer unix-tidsstemplet tilbage til en dato og klokkeslæt, tages tidszonen i betragtning, og det sker, at mellem den 28. og den 29. oktober 2006 gik vi fra sommertid og mistede en time.

Fra og med MySQL 4.1.3 returnerer funktionerne CURRENT_TIMESTAMP(), CURRENT_TIME(), CURRENT_DATE() og FROM_UNIXTIME() værdier i forbindelsens aktuelle tidszone , som er tilgængelig som værdien af ​​systemvariablen time_zone. Derudover antager UNIX_TIMESTAMP(), at dets argument er en datetime-værdi i den aktuelle tidszone.

Den aktuelle tidszoneindstilling påvirker ikke værdier, der vises af funktioner såsom UTC_TIMESTAMP() eller værdier i kolonnerne DATE, TIME eller DATETIME.

BEMÆRK:PÅ OPDATERING KUN opdaterer DateTime, hvis et felt ændres. Hvis en OPDATERING resulterer i, at ingen felter ændres, opdateres DateTime IKKE!

Derudover er First TIMESTAMP altid AUTOUPDATE som standard, selvom det ikke er angivet

Når jeg arbejder med Dates, tænker jeg næsten altid til Julian Date, fordi datamatematik så er et simpelt spørgsmål om at tilføje eller subtrahere heltal og sekunder siden midnat af samme grund. Det er sjældent, jeg har brug for tidsopløsning af finere granularitet end sekunder.

Begge disse kan gemmes som et 4 byte heltal, og hvis pladsen er virkelig knap, kan de kombineres til UNIX-tid (sekunder siden epoken 1/1/1970) som et heltal uden fortegn, der vil være godt indtil omkring 2106 som:

' sek på 24 timer =86400

' Signeret heltal max val =2.147.483.647 - kan indeholde 68 års sekunder

' Ikke-signeret heltal max val =4.294.967.295 - kan indeholde 136 års sekunder

Binær protokol:

MySQL 4.1 introducerede en binær protokol, der tillader ikke-strengdataværdier at blive sendt og returneret i native format uden konvertering til og fra strengformat. (Meget nyttigt)

Bortset fra, mysql_real_query() er hurtigere end mysql_query(), fordi den ikke kalder strlen() for at operere på sætningsstrengen.

http://dev.mysql.com/tech-resources /articles/4.1/prepared-statements.html Den binære protokol understøtter forberedte sætninger på serversiden og tillader transmission af dataværdier i native format. Den binære protokol gennemgik en del revision under de tidligere udgivelser af MySQL 4.1.

Du kan bruge makroen IS_NUM() til at teste, om et felt har en numerisk type. Send typeværdien til IS_NUM(), og den evalueres til TRUE, hvis feltet er numerisk:

En ting at bemærke er, at binære data KAN sendes i en almindelig forespørgsel, hvis du undslipper den og husker, at MySQL kun kræver at omvendt skråstreg og anførselstegn undgås. Så det er en rigtig nem måde at INDSÆTTE kortere binære strenge som f.eks. krypterede/saltede adgangskoder.

Hovedserver:

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

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

TILDEL REPLIKATIONSSLAVE PÅ . til slave_user IDENTIFICERET AF '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

Binær logfil skal læse:

http://dev.mysql.com/doc/refman /5.0/da/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 /da/mysqlbinlog.html

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

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

Du kan slette alle binære logfiler med RESET MASTER-sætningen eller en undergruppe af dem med PURGE MASTER

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

Normalisering:

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

UDF-funktioner

http://www.koders.com/cpp/fid106666379412ACDEB10DCDF106666379412ADCdF1066637941000000000000000000000000000000000000

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

Datatyper:

http://dev.mysql.com/doc/refman /5.1/da/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/

En ting at bemærke er, at på et blandet bord med både CHAR og VARCHAR, vil mySQL ændre CHAR'erne til VARCHAR's

RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMÆR NØGLE (RecNum)

MySQL repræsenterer altid datoer med året først, i overensstemmelse med standard SQL- og ISO 8601-specifikationerne

Diverse:

Deaktivering af nogle MySQl-funktioner vil resultere i mindre datafiler og hurtigere adgang. For eksempel:

--datadir vil angive databiblioteket og

--skip-innodb vil deaktivere inno-indstillingen og spare dig 10-20M

Mere herhttp://dev.mysql.com/tech -resources/articles/mysql-c-api.html

Download Kapitel 7 - Gratis

InnoDB er transaktionsbestemt, men der er en præstationsomkostning, der følger med. Jeg har fundet ud af, at MyISAM-tabeller er tilstrækkelige til 90 % af mine projekter. Ikke-transaktionssikre tabeller (MyISAM) har adskillige egne fordele, som alle opstår fordi:

der er ingen transaktionsomkostninger:

Meget hurtigere

Lavere krav til diskplads

Mindre hukommelse kræves for at udføre opdateringer

Hver MyISAM-tabel er gemt på disken i tre filer. Filerne har navne, der begynder med tabelnavnet og har en udvidelse til at angive filtypen. En .frm-fil gemmer tabelformatet. Datafilen har filtypenavnet .MYD (MYData). Indeksfilen har filtypenavnet .MYI (MYIndex).

Disse filer kan kopieres til en lagerplacering intakt uden at bruge MySQL Administrators Backup-funktionen, som er tidskrævende (det samme er gendannelsen)

Tricket er at lave en kopi af disse filer og derefter SLADE bordet. Når du sætter filerne tilbage, genkender MySQl dem og opdaterer tabelsporingen.

Hvis du skal sikkerhedskopiere/gendan,

Gendannelse af en sikkerhedskopi eller import fra en eksisterende dumpfil kan tage lang tid afhængigt af antallet af indekser og primærnøgler, du har på hver tabel. Du kan fremskynde denne proces dramatisk ved at ændre din originale dumpfil ved at omgive den med følgende:

SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;

.. your dump file ..

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

For at øge hastigheden på genindlæsningen markant, tilføj SQL-kommandoen SET AUTOCOMMIT =0; i begyndelsen af ​​dump-filen, og tilføj COMMIT; kommando til slutningen.

Som standard er autocommit slået til, hvilket betyder, at hver eneste indsæt-kommando i dump-filen vil blive behandlet som en separat transaktion og skrevet til disk, før den næste startes. Hvis du ikke tilføjer disse kommandoer, kan det tage mange timer at genindlæse en stor database i InnoDB...

Den maksimale størrelse på en række i en MySQL-tabel er 65.535 bytes

Den effektive maksimale længde af en VARCHAR i MySQL 5.0.3 og nyere =maksimal rækkestørrelse (65.535 bytes)

VARCHAR-værdier udfyldes ikke, når de gemmes. Efterfølgende mellemrum bevares, når værdier gemmes og hentes i overensstemmelse med standard SQL.

CHAR- og VARCHAR-værdier i MySQL sammenlignes uden hensyn til efterfølgende mellemrum.

Brug af CHAR vil kun fremskynde din adgang, hvis hele posten er fast størrelse. Det vil sige, at hvis du bruger et objekt med variabel størrelse, kan du lige så godt gøre dem alle til variabel størrelse. Du opnår ingen hastighed ved at bruge en CHAR i en tabel, der også indeholder en VARCHAR.

VARCHAR-grænsen på 255 tegn blev hævet til 65535 tegn fra MySQL 5.0.3

Fuldtekstsøgninger understøttes kun for MyISAM-tabeller.

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

BLOB-kolonner har intet tegnsæt, og sortering og sammenligning er baseret på de numeriske værdier af bytes i kolonneværdier

Hvis streng SQL-tilstand ikke er aktiveret, og du tildeler en værdi til en BLOB- eller TEKST-kolonne, der overstiger kolonnens maksimale længde, afkortes værdien, så den passer, og der genereres en advarsel.

Nyttige kommandoer:

check strict mode:SELECT @@global.sql_mode;

slå streng tilstand fra:

SET @@global.sql_mode='';

SET @@global.sql_mode='MYSQL40'

eller fjern:sql-mode="STRICT_TRANS_TABLES,...

VIS KOLONNER FRA mytable

SELECT max(namecount) AS virtualcolumn FRA mintabel BESTIL EFTER virtuel kolonne

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

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

giver dig PK'en for den sidste række indsat i den aktuelle tråd max(pkcolname) giver dig sidste PK samlet set.

Bemærk:hvis tabellen er tom, returnerer max(pkcolname) 1 mysql_insert_id() konverterer returtypen for den oprindelige MySQL C API-funktion mysql_insert_id() til en type oflong (navngivet int i PHP).

Hvis din AUTO_INCREMENT-kolonne har en kolonnetype BIGINT, vil den returnerede værdi af mysql_insert_id() være forkert. Brug i stedet den interne MySQL SQL-funktion LAST_INSERT_ID() i en SQL-forespørgsel.

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

Bare en bemærkning, at når du forsøger at indsætte data i en tabel, og du får fejlen:

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

ved at bruge noget som

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

det er fordi du ikke har nogen apostrof omkring de værdier du forsøger at stikke ind i bordet. Så du bør ændre din kode til:

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

påmindelse om, at `` bruges til at definere MySQL-felter, databaser eller tabeller, ikke værdier;)

Mistet forbindelse til server under forespørgsel:

http://dev.mysql.com/doc/refman /5.1/da/gone-away.html

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

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

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

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

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

Justeringsforespørgsler

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

Nå, det burde være nok til at tjene bonussen, vil jeg tro... Frugterne af mange timer og mange projekter med en fantastisk gratis database. Jeg udvikler applikationsdataservere på Windows-platforme for det meste med MySQL. Det værste rod, jeg skulle rette op på, var

Det ultimative MySQL-legacy-databasemareridt

Dette krævede en række applikationer til at bearbejde tabellerne til noget brugbart ved hjælp af mange af de tricks, der er nævnt her.

Hvis du fandt dette forbavsende nyttigt, så udtryk din tak ved at stemme det op.

Se også mine andre artikler og hvidbøger på:www.coastrd.com



  1. opdatere forespørgsel med join på to tabeller

  2. MuleSoft omfavner GraphQL til at fremme API-integration

  3. ETIMEDOUT fejl ved forespørgsel i mysql database

  4. Find ledigt værelse (booking system)