sql >> Databasteknik >  >> RDS >> Mysql

Dolda funktioner i MySQL

Eftersom du lägger ut en prispeng kommer jag att dela med mig av mina hemligheter som jag har vunnit hårt...

I allmänhet krävde alla SQL:er jag ställde in idag med hjälp av underfrågor. Efter att ha kommit från Oracles databasvärld fungerade saker som jag tog för givet inte på samma sätt med MySQL. Och min läsning om MySQL-tuning får mig att dra slutsatsen att MySQL ligger bakom Oracle när det gäller att optimera frågor.

Även om de enkla frågorna som krävs för de flesta B2C-applikationer kan fungera bra för MySQL, verkar de flesta av den samlade rapporteringstypen av frågor som behövs för Intelligence Reporting kräva en hel del planering och omorganisering av SQL-frågorna för att vägleda MySQL att exekvera dem snabbare.

Administration:

max_connections är antalet samtidiga anslutningar. Standardvärdet är 100 anslutningar (151 sedan 5.0) - mycket litet.

Obs:

anslutningar tar minne och ditt operativsystem kanske inte kan hantera många anslutningar.

MySQL-binärfiler för Linux/x86 tillåter dig att ha upp till 4096 samtidiga anslutningar, men självkompilerade binärer har ofta mindre gränser.

Ställ in table_cache för att matcha antalet öppna tabeller och samtidiga anslutningar. Titta på open_tables-värdet och om det växer snabbt måste du öka dess storlek.

Obs:

De två föregående parametrarna kan kräva många öppna filer. 20+max_connections+table_cache*2 är en bra uppskattning för vad du behöver. MySQL på Linux har ett open_file_limit-alternativ, ställ in denna gräns.

Om du har komplexa frågor är sort_buffer_size och tmp_table_size sannolikt mycket viktiga. Värden beror på frågekomplexiteten och tillgängliga resurser, men 4 Mb respektive 32 Mb är rekommenderade utgångspunkter.

Obs:Dessa är "per anslutning"-värden, bland read_buffer_size, read_rnd_buffer_size och några andra, vilket betyder att detta värde kan behövas för varje anslutning. Så ta hänsyn till din belastning och tillgängliga resurser när du ställer in dessa parametrar. Till exempel tilldelas sort_buffer_size endast om MySQL behöver göra en sortering. Obs:var försiktig så att du inte får ont om minne.

Om du har många anslutningar etablerade (dvs. en webbplats utan beständiga anslutningar) kan du förbättra prestandan genom att ställa in thread_cache_size till ett värde som inte är noll. 16 är bra värde att börja med. Öka värdet tills dina threads_created inte växer särskilt snabbt.

PRIMÄRNYCKEL:

Det kan bara finnas en AUTO_INCREMENT-kolumn per tabell, den måste indexeras och den kan inte ha ett DEFAULT-värde

KEY är normalt en synonym för INDEX. Nyckelattributet PRIMARY KEY kan också anges som bara KEY när det ges i en kolumndefinition. Detta implementerades för kompatibilitet med andra databassystem.

EN PRIMÄRNYCKEL är ett unikt index där alla nyckelkolumner måste definieras som INTE NULL

Om ett PRIMARY KEY eller UNIQUE index består av endast en kolumn som har en heltalstyp, kan du även referera till kolumnen som "_rowid" i SELECT-satser.

I MySQL är namnet på en PRIMÄRNYCKEL PRIMÄR

För närvarande är det bara InnoDB (v5.1?)-tabeller som stöder främmande nycklar.

Vanligtvis skapar du alla index du behöver när du skapar tabeller. Alla kolumner som deklareras som PRIMÄRKEY, KEY, UNIQUE eller INDEX kommer att indexeras.

NULL betyder "inte har ett värde". För att testa för NULL kan du inte använd aritmetiska jämförelseoperatorer som =, . Använd operatorerna IS NULL och IS NOT NULL istället:

NO_AUTO_VALUE_ON_ZERO undertrycker automatisk ökning för 0 så att endast NULL genererar nästa sekvensnummer. Detta läge kan vara användbart om 0 har lagrats i en tabells kolumn AUTO_INCREMENT. (Att lagra 0 är förresten inte en rekommenderad praxis.)

För att ändra värdet på AUTO_INCREMENT-räknaren som ska användas för nya rader:

ALTER TABLE mytable AUTO_INCREMENT = value; 

ellerSET INSERT_ID =värde;

Om inget annat anges kommer värdet att börja med:1000000 eller specificera det så här:

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

TIDSSTÄMPLAR:

Värden för TIMESTAMP-kolumner konverteras från den aktuella tidszonen till UTC för lagring och från UTC till den aktuella tidszonen för hämtning.

http://dev.mysql.com/doc/refman/5.1 /en/timestamp.html För en TIMESTAMP-kolumn i en tabell kan du tilldela den aktuella tidsstämpeln som standardvärde och värdet för automatisk uppdatering.

en sak att se upp med när du använder en av dessa typer i en WHERE-klausul är det bäst att doWHERE datecolumn =FROM_UNIXTIME(1057941242) och notWHERE UNIX_TIMESTAMP(datecolumn) =1057941242. Om du gör det senare kommer inte att dra fördel av ett index på det kolumn.

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

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

om du konverterar en datetime till unix timestamp i MySQL:
Och sedan lägger till 24 timmar till den:
Och sedan konverterar den tillbaka till en datetime, förlorar den magiskt en timme!

Här är vad som händer. När man konverterar unix-tidsstämpeln tillbaka till en datetime tas tidszonen i beaktande och det råkar vara så att vi mellan den 28:e och 29:e oktober 2006 avbröt sommartid och förlorade en timme.

Från och med MySQL 4.1.3 returnerar funktionerna CURRENT_TIMESTAMP(), CURRENT_TIME(), CURRENT_DATE() och FROM_UNIXTIME() värden i anslutningens aktuella tidszon , som är tillgängligt som värdet för systemvariabeln time_zone. Dessutom antar UNIX_TIMESTAMP() att dess argument är ett datetime-värde i den aktuella tidszonen.

Den aktuella tidszonsinställningen påverkar inte värden som visas av funktioner som UTC_TIMESTAMP() eller värden i kolumnerna DATE, TIME eller DATETIME.

OBS:VID UPPDATERING ENDAST uppdaterar DateTime om ett fält ändras Om en UPPDATERING resulterar i att inga fält ändras uppdateras INTE DateTime!

Dessutom är den första tidsstämpeln alltid AUTOUPPDATERING som standard även om den inte anges

När jag arbetar med Dates, tror jag nästan alltid på Julian Date eftersom datamatte då är en enkel fråga om att lägga till eller subtrahera heltal, och Seconds since Midnight av samma anledning. Det är sällsynt att jag behöver en tidsupplösning med finare granularitet än sekunder.

Båda dessa kan lagras som ett 4-byte heltal, och om utrymmet är riktigt trångt kan de kombineras till UNIX-tid (sekunder sedan epok 1/1/1970) som ett heltal utan tecken som kommer att vara bra till omkring 2106 som:

' sek på 24 timmar =86400

' Signerat heltal max val =2 147 483 647 - kan hålla 68 år av sekunder

' Osignerat heltal max val =4 294 967 295 - kan hålla 136 år av sekunder

Binärt protokoll:

MySQL 4.1 introducerade ett binärt protokoll som gör att icke-strängdatavärden kan skickas och returneras i inbyggt format utan konvertering till och från strängformat. (Mycket användbart)

Bortsett från, mysql_real_query() är snabbare än mysql_query() eftersom det inte anropar strlen() för att arbeta på satssträngen.

http://dev.mysql.com/tech-resources /articles/4.1/prepared-statements.html Det binära protokollet stöder förberedda uttalanden på serversidan och tillåter överföring av datavärden i eget format. Det binära protokollet genomgick en hel del revidering under de tidigare utgåvorna av MySQL 4.1.

Du kan använda makrot IS_NUM() för att testa om ett fält har en numerisk typ. Skicka typvärdet till IS_NUM() och det utvärderas till TRUE om fältet är numeriskt:

En sak att notera är att binär data KAN skickas i en vanlig fråga om du undkommer den och kommer ihåg att MySQL bara kräver att omvänt snedstreck och citattecknet undantas. Så det är ett riktigt enkelt sätt att INFOGA kortare binära strängar som krypterade/saltade lösenord till exempel.

Master Server:

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

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

BIDRAG REPLIKATIONSSLAV PÅ . till slave_user IDENTIFIERAD AV 'slave_lösenord'

#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 loggfil måste läsa:

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

Du kan ta bort alla binära loggfiler med RESET MASTER-satsen, eller en delmängd av 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/fid106666379412ACDEB10DEB1412ACDB1000000000000000000000000000000000000

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

Datatyper:

http://dev.mysql.com/doc/refman /5.1/sv/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 sak att notera är att på ett blandat bord med både CHAR och VARCHAR kommer mySQL att ändra CHAR till VARCHAR

RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMÄRNYCKEL (RecNum)

MySQL representerar alltid datum med året först, i enlighet med standardspecifikationerna för SQL och ISO 8601

Övrigt:

Att stänga av vissa MySQl-funktioner kommer att resultera i mindre datafiler och snabbare åtkomst. Till exempel:

--datadir kommer att ange datakatalogen och

--skip-innodb kommer att stänga av inno-alternativet och spara 10-20M

Mer härhttp://dev.mysql.com/tech -resources/articles/mysql-c-api.html

Ladda ner Kapitel 7 - Gratis

InnoDB är transaktionsmässigt men det finns en prestationsoverhead som följer med den. Jag har funnit att MyISAM-tabeller räcker till 90 % av mina projekt. Tabeller som inte är transaktionssäkra (MyISAM) har flera egna fördelar, som alla beror på:

det finns ingen transaktionsoverhead:

Mycket snabbare

Lägre diskutrymmeskrav

Mindre minne krävs för att utföra uppdateringar

Varje MyISAM-tabell lagras på disken i tre filer. Filerna har namn som börjar med tabellnamnet och har ett tillägg för att indikera filtypen. En .frm-fil lagrar tabellformatet. Datafilen har filtillägget .MYD (MYData). Indexfilen har filtillägget .MYI (MYIndex).

Dessa filer kan kopieras till en lagringsplats intakt utan att använda MySQL Administrators Backup-funktionen som är tidskrävande (så är återställningen)

Tricket är att göra en kopia av dessa filer och sedan släppa bordet. När du lägger tillbaka filerna kommer MySQl att känna igen dem och uppdatera tabellspårningen.

Om du måste säkerhetskopiera/återställa,

Att återställa en säkerhetskopia eller importera från en befintlig dumpfil kan ta lång tid beroende på antalet index och primärnycklar du har på varje tabell. Du kan påskynda processen dramatiskt genom att ändra din ursprungliga dumpfil genom att omge den med följande:

SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;

.. your dump file ..

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

För att avsevärt öka hastigheten på omladdningen, lägg till SQL-kommandot SET AUTOCOMMIT =0; i början av dumpfilen och lägg till COMMIT; kommando till slutet.

Som standard är autocommit på, vilket betyder att varje insert-kommando i dumpfilen kommer att behandlas som en separat transaktion och skrivas till disken innan nästa startas. Om du inte lägger till dessa kommandon kan det ta många timmar att ladda om en stor databas till InnoDB...

Den maximala storleken på en rad i en MySQL-tabell är 65 535 byte

Den effektiva maximala längden för en VARCHAR i MySQL 5.0.3 och på =maximal radstorlek (65 535 byte)

VARCHAR-värden är inte utfyllda när de lagras. Efterföljande utrymmen behålls när värden lagras och hämtas, i enlighet med standard SQL.

CHAR- och VARCHAR-värden i MySQL jämförs utan hänsyn till efterföljande mellanslag.

Att använda CHAR kommer bara att påskynda din åtkomst om hela posten är fast storlek. Det vill säga, om du använder ett objekt med variabel storlek, kan du lika gärna göra alla till variabel storlek. Du får ingen hastighet genom att använda en CHAR i en tabell som också innehåller en VARCHAR.

VARCHAR-gränsen på 255 tecken höjdes till 65535 tecken från och med MySQL 5.0.3

Fulltextsökningar stöds endast för MyISAM-tabeller.

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

BLOB-kolumner har ingen teckenuppsättning, och sortering och jämförelse baseras på de numeriska värdena för byte i kolumnvärden

Om strikt SQL-läge inte är aktiverat och du tilldelar ett värde till en BLOB- eller TEXT-kolumn som överskrider kolumnens maximala längd, trunkeras värdet för att passa och en varning genereras.

Användbara kommandon:

kontrollera strikt läge:SELECT @@global.sql_mode;

stäng av strikt läge:

SET @@global.sql_mode='';

SET @@global.sql_mode='MYSQL40'

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

VISA KOLUMNER FRÅN mytable

SELECT max(namecount) AS virtualcolumn FRÅN mytable BESTÄLL EFTER virtuell kolumn

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()

ger dig PK för den sista raden som infogades i den aktuella tråden max(pkcolname) får din sista PK totalt.

Obs:om tabellen är tom returnerar max(pkcolname) 1 mysql_insert_id() konverterar returtypen för den inbyggda MySQL C API-funktionen mysql_insert_id() till en typ oflong (benämnt int i PHP).

Om din AUTO_INCREMENT-kolumn har kolumntypen BIGINT, kommer värdet som returneras av mysql_insert_id() att vara felaktigt. Använd istället den interna MySQL SQL-funktionen LAST_INSERT_ID() i en SQL-fråga.

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

Bara en notering att när du försöker infoga data i en tabell och du får felet:

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

använder något liknande

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

det beror på att du inte har några apostrof kring de värderingar du försöker hålla fast vid bordet. Så du bör ändra din kod till:

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

påminnelse om att `` används för att definiera MySQL-fält, databaser eller tabeller, inte värden;)

Förlorade anslutningen till servern under fråga:

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

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

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

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

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

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

Justera frågor

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

Det borde räcka för att tjäna bonusen skulle jag tro... Frukterna av många timmar och många projekt med en fantastisk gratis databas. Jag utvecklar applikationsdataservrar på Windows-plattformar mestadels med MySQL. Den värsta röran jag var tvungen att reda ut var

Den ultimata MySQL äldre databas mardröm

Detta krävde en rad applikationer för att bearbeta tabellerna till något användbart med många av de knep som nämns här.

Om du tyckte att detta var häpnadsväckande användbart, uttrycka ditt tack genom att rösta upp det.

Kolla även in mina andra artiklar och vitböcker på:www.coastrd.com



  1. Hur man kör PHP-kod regelbundet på ett automatiskt sätt

  2. Hur man skriver en SQL-fråga med dynamisk LIMIT

  3. Relationella vs icke-relationella databaser – Del 3

  4. Olika sätt att fylla MySQL-användare