Odkąd wyznaczyłeś nagrodę, podzielę się moimi ciężko zdobytymi sekretami ...
Ogólnie rzecz biorąc, wszystkie SQL, które dostroiłem dzisiaj, wymagały użycia pod-zapytań. Pochodząc ze świata baz danych Oracle, rzeczy, które uważałem za oczywiste, nie działały tak samo z MySQL. Po przeczytaniu informacji o strojeniu MySQL dochodzę do wniosku, że MySQL stoi za Oracle pod względem optymalizacji zapytań.
Podczas gdy proste zapytania wymagane dla większości aplikacji B2C mogą dobrze działać w przypadku MySQL, większość zapytań typu zagregowanego raportowania potrzebnych do raportowania inteligencji wydaje się wymagać sporo planowania i reorganizacji zapytań SQL, tak aby MySQL wykonywał je szybciej.
Administracja:
max_connections
to liczba jednoczesnych połączeń. Wartość domyślna to 100 połączeń (151 od wersji 5.0) - bardzo mała.
Uwaga:
połączenia zajmują pamięć, a system operacyjny może nie być w stanie obsłużyć wielu połączeń.
Pliki binarne MySQL dla Linux / x86 pozwalają na posiadanie do 4096 jednoczesnych połączeń, ale pliki binarne skompilowane samodzielnie często mają mniejszy limit.
Ustaw table_cache tak, aby odpowiadała liczbie otwartych tabel i jednoczesnych połączeń. Obserwuj wartość open_tables, a jeśli szybko rośnie, musisz zwiększyć jego rozmiar.
Uwaga:
Dwa poprzednie parametry mogą wymagać wielu otwartych plików. 20 + max_connections + table_cache * 2 to dobre oszacowanie tego, czego potrzebujesz. MySQL w systemie Linux ma opcję open_file_limit, ustaw ten limit.
Jeśli masz złożone zapytania, sort_buffer_size i tmp_table_size będą prawdopodobnie bardzo ważne. Wartości będą zależeć od złożoności zapytania i dostępnych zasobów, ale odpowiednio 4 MB i 32 MB są zalecanymi punktami początkowymi.
Uwaga: są to wartości „na połączenie”, między innymi read_buffer_size, read_rnd_buffer_size i kilka innych, co oznacza, że ta wartość może być potrzebna dla każdego połączenia. Dlatego podczas ustawiania tych parametrów należy wziąć pod uwagę obciążenie i dostępne zasoby. Na przykład sort_buffer_size jest przydzielany tylko wtedy, gdy MySQL musi wykonać sortowanie. Uwaga: uważaj, aby nie zabrakło pamięci.
Jeśli masz ustanowionych wiele połączeń (np. Witryna internetowa bez trwałych połączeń), możesz poprawić wydajność, ustawiając wartość thread_cache_size na wartość niezerową. 16 to dobra wartość na początek. Zwiększaj wartość, dopóki twoje wątki_created nie będą rosły bardzo szybko.
KLUCZ PODSTAWOWY:
W tabeli może istnieć tylko jedna kolumna AUTO_INCREMENT, musi być zindeksowana i nie może mieć wartości DEFAULT
KEY jest zwykle synonimem INDEX. Atrybut klucza PRIMARY KEY można również określić jako po prostu KEY, jeśli jest podany w definicji kolumny. Zostało to zaimplementowane w celu zapewnienia zgodności z innymi systemami baz danych.
KLUCZ PODSTAWOWY to unikalny indeks, w którym wszystkie kolumny kluczy muszą być zdefiniowane jako NIE NULL
Jeśli indeks PRIMARY KEY lub UNIQUE składa się tylko z jednej kolumny o typie całkowitym, w instrukcjach SELECT można również odwoływać się do kolumny jako „_rowid”.
W MySQL nazwa KLUCZA PODSTAWOWEGO to PRIMARY
Obecnie tylko tabele InnoDB (v5.1?) Obsługują klucze obce.
Zwykle wszystkie indeksy są potrzebne podczas tworzenia tabel. Każda kolumna zadeklarowana jako PRIMARY KEY, KEY, UNIQUE lub INDEX będzie indeksowana.
NULL oznacza „brak wartości”. Aby przetestować wartość NULL, nie można użyć arytmetycznych operatorów porównania, takich jak =, <lub <>. Zamiast tego użyj operatorów IS NULL i IS NOT NULL:
NO_AUTO_VALUE_ON_ZERO wstrzymuje automatyczne zwiększanie wartości 0, tak że tylko NULL generuje następny numer sekwencyjny. Ten tryb może być przydatny, jeśli 0 zostało zapisane w kolumnie AUTO_INCREMENT tabeli. (Nawiasem mówiąc, przechowywanie 0 nie jest zalecaną praktyką).
Aby zmienić wartość licznika AUTO_INCREMENT, który ma być używany dla nowych wierszy:
ALTER TABLE mytable AUTO_INCREMENT = value;
lub SET INSERT_ID = wartość;
O ile nie określono inaczej, wartość zaczyna się od: 1000000 lub określa ją w ten sposób:
...) ENGINE = MyISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT = 1
CZASOMIERZ:
Wartości kolumn TIMESTAMP są konwertowane z bieżącej strefy czasowej na UTC w celu przechowywania iz UTC na bieżącą strefę czasową w celu pobrania.
http://dev.mysql.com/doc/refman/5.1/en/timestamp.html
W przypadku jednej kolumny TIMESTAMP w tabeli można przypisać bieżący znacznik czasu jako wartość domyślną i wartość automatycznej aktualizacji.
jedna rzecz, na którą należy uważać podczas używania jednego z tych typów w klauzuli WHERE, najlepiej jest zrobić WHERE datecolumn = FROM_UNIXTIME (1057941242), a nie WHERE UNIX_TIMESTAMP (datecolumn) = 1057941242. zrobienie tego drugiego nie wykorzysta indeksu na tej kolumnie.
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
UNIX_TIMESTAMP()
FROM_UNIXTIME()
UTC_DATE()
UTC_TIME()
UTC_TIMESTAMP()
jeśli przekonwertujesz datetime na unix timestamp w MySQL:
A potem dodaj do tego 24 godziny:
A potem przekonwertuj z powrotem na datę i godzinę, magicznie traci godzinę!
Oto, co się dzieje. Podczas konwersji uniksowego znacznika czasu z powrotem na datę i godzinę, strefa czasowa jest brana pod uwagę i tak się składa, że między 28 a 29 października 2006 straciliśmy czas letni i godzinę.
Począwszy od MySQL 4.1.3, funkcje CURRENT_TIMESTAMP (), CURRENT_TIME (), CURRENT_DATE () i FROM_UNIXTIME () zwracają wartości w bieżącej strefie czasowej połączenia , która jest dostępna jako wartość zmiennej systemowej time_zone. Ponadto UNIX_TIMESTAMP () zakłada, że jej argument jest wartością typu data-godzina w bieżącej strefie czasowej.
Bieżące ustawienie strefy czasowej nie wpływa na wartości wyświetlane przez funkcje, takie jak UTC_TIMESTAMP () lub wartości w kolumnach DATA, CZAS lub DATETIME.
UWAGA: TYLKO PRZY AKTUALIZACJI aktualizuje datę i godzinę, jeśli pole zostanie zmienione. Jeśli AKTUALIZACJA nie powoduje zmiany żadnych pól, wówczas data i godzina NIE są aktualizowane!
Dodatkowo, pierwszy TIMESTAMP to zawsze AUTOUPDATE, nawet jeśli nie został określony
Podczas pracy z datami prawie zawsze konwertuję na datę juliańską, ponieważ matematyka danych jest wtedy prostą kwestią dodawania lub odejmowania liczb całkowitych i sekund od północy z tego samego powodu. Rzadko potrzebuję czasu o większej ziarnistości niż sekundy.
Obydwa mogą być przechowywane jako 4-bajtowe liczby całkowite, a jeśli przestrzeń jest naprawdę mała, można je połączyć w czas UNIX (sekundy od epoki 1/1/1970) jako liczbę całkowitą bez znaku, która będzie dobra do około 2106 jako:
's w ciągu 24 godzin = 86400
„Signed Integer max val = 2.147.483.647 - może pomieścić 68 lat sekund
„Unsigned Integer max val = 4 294 967 295 - może pomieścić 136 lat sekund
Protokół binarny:
MySQL 4.1 wprowadził protokół binarny, który umożliwia wysyłanie i zwracanie wartości danych niebędących ciągami znaków w formacie natywnym bez konwersji na format łańcuchowy iz powrotem. (Bardzo użyteczne)
Poza tym mysql_real_query () jest szybsza niż mysql_query (), ponieważ nie wywołuje strlen () do działania na ciągu instrukcji.
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
Protokół binarny obsługuje instrukcje przygotowane po stronie serwera i umożliwia przesyłanie wartości danych w formacie natywnym. Protokół binarny przeszedł sporo zmian we wcześniejszych wydaniach MySQL 4.1.
Możesz użyć makra IS_NUM (), aby sprawdzić, czy pole ma typ liczbowy. Przekaż wartość typu do IS_NUM () i zwraca wartość PRAWDA, jeśli pole jest numeryczne:
Należy zauważyć, że dane binarne MOGĄ być wysyłane w ramach zwykłego zapytania, jeśli uciekniesz przed nim i pamiętaj, że MySQL wymaga tylko tego ukośnika odwrotnego i cudzysłowu. Jest to więc naprawdę łatwy sposób na WSTAWIANIE krótszych ciągów binarnych, takich jak na przykład zaszyfrowane / solone hasła.
Serwer główny:
http://www.experts-exchange.com/Database/MySQL/Q_22967482.html
http://www.databasejournal.com/features/mysql/article.php/10897_3355201_2
GRANT REPLICATION SLAVE ON . to slave_user IDENTIFIED BY „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
Plik dziennika binarnego musi czytać:
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
Możesz usunąć wszystkie binarne pliki dziennika za pomocą instrukcji RESET MASTER lub ich podzbiór za pomocą polecenia PURGE MASTER
--result-file = binlog.txt TrustedFriend-bin.000030
Normalizacja:
http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html
Funkcje UDF
http://www.koders.com/cpp/fid10666379322B54AD41AEB0E4100D87C8CDDF1D8C.aspx
http://souptonuts.sourceforge.net/readme_mysql.htm
Typy danych:
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/
Należy zwrócić uwagę na to, że na mieszanej tabeli z CHAR i VARCHAR mySQL zmieni CHAR na VARCHAR
RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (RecNum)
MySQL zawsze przedstawia daty zaczynając od roku, zgodnie ze standardowymi specyfikacjami SQL i ISO 8601
Różne:
Wyłączenie niektórych funkcji MySQl spowoduje zmniejszenie plików danych i szybszy dostęp. Na przykład:
--datadir określi katalog danych i
--skip-innodb wyłączy opcję inno i zaoszczędzi 10-20 mln
Więcej tutaj
http://dev.mysql.com/tech-resources/articles/mysql-c-api.html
Pobierz rozdział 7 - bezpłatny
InnoDB jest platformą transakcyjną, ale wiąże się z nią narzut wydajności. Stwierdziłem, że tabele MyISAM wystarczają na 90% moich projektów. Tabele niezabezpieczone transakcjami (MyISAM) mają kilka własnych zalet, z których wszystkie występują, ponieważ:
nie ma narzutów transakcyjnych:
O wiele szybciej
Mniejsze wymagania dotyczące miejsca na dysku
Do wykonania aktualizacji potrzeba mniej pamięci
Każda tabela MyISAM jest przechowywana na dysku w trzech plikach. Pliki mają nazwy zaczynające się od nazwy tabeli i mają rozszerzenie wskazujące na typ pliku. Plik .frm przechowuje format tabeli. Plik danych ma rozszerzenie .MYD (MYData). Plik indeksu ma rozszerzenie .MYI (MYIndex).
Te pliki można skopiować do lokalizacji przechowywania w stanie nienaruszonym bez korzystania z funkcji kopii zapasowej administratorów MySQL, która jest czasochłonna (podobnie jak przywracanie)
Sztuczka polega na zrobieniu kopii tych plików, a następnie UPUSZCZENIE tabeli. Po przywróceniu plików MySQl rozpozna je i zaktualizuje śledzenie tabeli.
Jeśli musisz wykonać kopię zapasową / przywrócić,
Przywracanie kopii zapasowej lub importowanie z istniejącego pliku zrzutu może zająć dużo czasu w zależności od liczby indeksów i kluczy podstawowych w każdej tabeli. Możesz znacznie przyspieszyć ten proces, modyfikując oryginalny plik zrzutu, otaczając go następującymi elementami:
SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;
.. your dump file ..
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;
Aby znacznie zwiększyć szybkość przeładowania, dodaj polecenie SQL SET AUTOCOMMIT = 0; na początku pliku zrzutu i dodaj COMMIT; polecenie do końca.
Domyślnie autocommit jest włączone, co oznacza, że każde polecenie wstawiania w pliku zrzutu będzie traktowane jako oddzielna transakcja i zapisywane na dysku przed rozpoczęciem następnej. Jeśli nie dodasz tych poleceń, ponowne załadowanie dużej bazy danych do InnoDB może zająć wiele godzin ...
Maksymalny rozmiar wiersza w tabeli MySQL to 65 535 bajtów
Efektywna maksymalna długość VARCHAR w MySQL 5.0.3 i dalej = maksymalny rozmiar wiersza (65 535 bajtów)
Wartości VARCHAR nie są wypełniane, gdy są przechowywane. Spacje końcowe są zachowywane, gdy wartości są zapisywane i pobierane, zgodnie ze standardowym SQL.
Wartości CHAR i VARCHAR w MySQL są porównywane bez względu na końcowe spacje.
Użycie znaku CHAR przyspieszy dostęp tylko wtedy, gdy cały rekord ma stały rozmiar. Oznacza to, że jeśli używasz dowolnego obiektu o zmiennej wielkości, równie dobrze możesz sprawić, że wszystkie będą miały zmienny rozmiar. Nie zyskujesz szybkości, używając znaku CHAR w tabeli zawierającej również VARCHAR.
Limit VARCHAR 255 znaków został podniesiony do 65535 znaków od MySQL 5.0.3
Wyszukiwanie pełnotekstowe jest obsługiwane tylko w przypadku tabel MyISAM.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
Kolumny BLOB nie mają zestawu znaków, a sortowanie i porównanie są oparte na wartościach liczbowych bajtów w wartościach kolumn
Jeśli tryb ścisłego SQL nie jest włączony i do kolumny BLOB lub TEXT zostanie przypisana wartość przekraczająca maksymalną długość kolumny, wartość zostanie obcięta w celu dopasowania i zostanie wygenerowane ostrzeżenie.
Przydatne polecenia:
sprawdź tryb ścisły: SELECT @@ global.sql_mode;
wyłącz tryb ścisły:
SET @@ global.sql_mode = '';
SET @@ global.sql_mode = 'MYSQL40'
lub usuń: sql-mode = "STRICT_TRANS_TABLES, ...
POKAŻ KOLUMNY Z mytable
SELECT max (namecount) AS virtualcolumn
FROM mytable ORDER BY virtualcolumn
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 ()
pobiera PK z ostatniego wiersza wstawionego w bieżącym wątku. max (pkcolname) pobiera ostatni PK w całości.
Uwaga: jeśli tabela jest pusta, max (pkcolname) zwraca 1 mysql_insert_id () konwertuje zwracany typ natywnej funkcji MySQL C API mysql_insert_id () na typ long (nazwany int w PHP).
Jeśli kolumna AUTO_INCREMENT ma typ kolumny BIGINT, wartość zwrócona przez mysql_insert_id () będzie niepoprawna. Zamiast tego użyj wewnętrznej funkcji MySQL SQL LAST_INSERT_ID () w zapytaniu SQL.
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
Tylko uwaga, że kiedy próbujesz wstawić dane do tabeli i otrzymujesz błąd:
Unknown column ‘the first bit of data what you want to put into the table‘ in ‘field list’
używając czegoś takiego jak
INSERT INTO table (this, that) VALUES ($this, $that)
dzieje się tak dlatego, że nie masz żadnych apostrofów wokół wartości, które próbujesz umieścić w tabeli. Więc powinieneś zmienić swój kod na:
INSERT INTO table (this, that) VALUES ('$this', '$that')
przypomnienie, że `` służą do definiowania pól MySQL, baz danych lub tabel, a nie wartości;)
Utracone połączenie z serwerem podczas zapytania:
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/en/option-files.html
http://dev.mysql.com/doc/refman/5.1/en/error-log.html
Zapytania dostrajające
http://www.artfulsoftware.com/infotree/queries.php?&bw=1313
Cóż, to powinno wystarczyć, by zarobić bonus, myślę, że ... Owoce wielu godzin i wielu projektów ze świetną darmową bazą danych. Rozwijam serwery danych aplikacji na platformach Windows głównie z MySQL. Najgorszy bałagan, jaki musiałem uporządkować, to
Ostateczny koszmar starej bazy danych MySQL
Wymagało to szeregu aplikacji, aby przetworzyć tabele w coś użytecznego przy użyciu wielu wspomnianych tutaj sztuczek.
Jeśli uznasz to za zdumiewająco pomocne, wyrażaj swoje podziękowania, głosując.
Sprawdź także moje inne artykuły i białe księgi na: www.coastrd.com