私は長年Microsoft SQL Serverを使用してきましたが、Web アプリケーションでMySQLを使い始めたのはつい最近のことであり、知識に飢えています。
「隠れた機能」に関する質問の長い列を続けるために、MySQL の隠れた機能や便利な機能を知りたいと思います。これにより、このオープン ソース データベースの知識が向上することが期待されます。
私は長年Microsoft SQL Serverを使用してきましたが、Web アプリケーションでMySQLを使い始めたのはつい最近のことであり、知識に飢えています。
「隠れた機能」に関する質問の長い列を続けるために、MySQL の隠れた機能や便利な機能を知りたいと思います。これにより、このオープン ソース データベースの知識が向上することが期待されます。
懸賞金をかけてくれたので、苦労して手に入れた秘密を共有します...
一般に、今日チューニングしたすべての SQL では、サブクエリを使用する必要がありました。Oracle データベースの世界から来た私は、当たり前だと思っていたことが MySQL ではうまくいきませんでした。また、MySQL のチューニングについて読んだ結果、MySQL はクエリの最適化に関して Oracle に遅れをとっていると結論付けました。
ほとんどの B2C アプリケーションに必要な単純なクエリは MySQL でうまく機能する可能性がありますが、Intelligence Reporting に必要な集計レポート タイプのクエリのほとんどは、MySQL がより高速に実行できるように SQL クエリをかなり計画および再編成する必要があるようです。
max_connections
同時接続数です。デフォルト値は 100 接続 (5.0 以降は 151) で、非常に小さいです。
ノート:
接続はメモリを消費し、OS が多くの接続を処理できない可能性があります。
Linux/x86 用の MySQL バイナリでは最大 4096 の同時接続が許可されますが、セルフ コンパイルされたバイナリでは制限が少ないことがよくあります。
開いているテーブルと同時接続の数に一致するように table_cache を設定します。open_tables の値を監視します。値が急速に大きくなっている場合は、サイズを大きくする必要があります。
ノート:
前の 2 つのパラメーターでは、多数の開いているファイルが必要になる場合があります。20+max_connections+table_cache*2 は、必要なものの適切な見積もりです。Linux 上の MySQL には open_file_limit オプションがあり、この制限を設定します。
複雑なクエリがある場合、sort_buffer_size と tmp_table_size が非常に重要になる可能性があります。値はクエリの複雑さと利用可能なリソースによって異なりますが、それぞれ 4Mb と 32Mb が推奨される開始点です。
注: これらは、read_buffer_size、read_rnd_buffer_size などの「接続ごと」の値であり、接続ごとにこの値が必要になる可能性があることを意味します。したがって、これらのパラメーターを設定するときは、負荷と使用可能なリソースを考慮してください。たとえば、sort_buffer_size は、MySQL がソートを実行する必要がある場合にのみ割り当てられます。注: メモリが不足しないように注意してください。
多数の接続が確立されている場合 (つまり、永続的な接続のない Web サイト)、thread_cache_size をゼロ以外の値に設定すると、パフォーマンスが向上する可能性があります。16 は、最初は適切な値です。値を増やして、threads_created がすぐに大きくならないようにします。
テーブルごとに 1 つの AUTO_INCREMENT カラムしか存在できず、インデックスを作成する必要があり、DEFAULT 値を持つことはできません
通常、KEY は INDEX と同義です。キー属性 PRIMARY KEY は、列定義で指定されている場合、単に KEY として指定することもできます。これは、他のデータベース システムとの互換性のために実装されました。
PRIMARY KEY は、すべてのキー列を NOT NULL として定義する必要がある一意のインデックスです。
PRIMARY KEY または UNIQUE インデックスが整数型の 1 つの列のみで構成されている場合、その列を SELECT ステートメントで "_rowid" として参照することもできます。
MySQL では、PRIMARY KEY の名前は PRIMARY です。
現在、InnoDB (v5.1?) テーブルのみが外部キーをサポートしています。
通常、テーブルを作成するときに、必要なすべてのインデックスを作成します。PRIMARY KEY、KEY、UNIQUE、または INDEX として宣言された列には、インデックスが作成されます。
NULL は「値がない」ことを意味します。NULL をテストするために、=、<、<> などの算術比較演算子は使用できません。代わりに IS NULL および IS NOT NULL 演算子を使用します。
NO_AUTO_VALUE_ON_ZERO は 0 の自動インクリメントを抑制し、NULL のみが次のシーケンス番号を生成するようにします。このモードは、テーブルの AUTO_INCREMENT 列に 0 が格納されている場合に役立ちます。(ちなみに、0 を格納することはお勧めできません。)
新しい行に使用される AUTO_INCREMENT カウンターの値を変更するには、次のようにします。
ALTER TABLE mytable AUTO_INCREMENT = value;
または SET INSERT_ID = 値;
特に指定がない限り、値は 1000000 で始まるか、次のように指定します。
...) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1
TIMESTAMP 列の値は、現在のタイム ゾーンから UTC に変換されて保存され、UTC から現在のタイム ゾーンに変換されて取得されます。
http://dev.mysql.com/doc/refman/5.1/en/timestamp.html テーブル内の 1 つの TIMESTAMP 列に対して、現在のタイムスタンプをデフォルト値および自動更新値として割り当てることができます。
WHERE 句でこれらのタイプのいずれかを使用する場合に注意すべきことの 1 つは、WHERE UNIX_TIMESTAMP(datecolumn) = 1057941242 ではなく、WHERE datecolumn = FROM_UNIXTIME(1057941242) を実行することです。後者を実行すると、インデックスを利用できません。その列に。
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
UNIX_TIMESTAMP()
FROM_UNIXTIME()
UTC_DATE()
UTC_TIME()
UTC_TIMESTAMP()
MySQL で datetime を unix タイムスタンプに変換すると:
そしてそれに 24 時間を追加します: そしてそれ
を datetime に戻すと、魔法のように 1 時間が失われます!
これが何が起こっているかです。Unix タイムスタンプを日時に変換する際、タイムゾーンが考慮されますが、たまたま 2006 年 10 月 28 日から 29 日の間に夏時間から外れて 1 時間が失われました。
MySQL 4.1.3 から、CURRENT_TIMESTAMP()、CURRENT_TIME()、CURRENT_DATE()、および FROM_UNIXTIME() 関数は、 time_zone システム変数の値として利用可能な接続の現在のタイム ゾーンで値を返します。さらに、UNIX_TIMESTAMP() は、その引数が現在のタイム ゾーンの日時値であると想定します。
現在のタイム ゾーン設定は、UTC_TIMESTAMP() などの関数によって表示される値や、DATE、TIME、または DATETIME 列の値には影響しません。
注: ON UPDATEは、フィールドが変更された場合にのみ DateTime を更新します。UPDATE の結果、フィールドが変更されない場合、DateTime は更新されません。
さらに、最初の TIMESTAMP は、指定されていなくてもデフォルトで常に AUTOUPDATE です。
日付を扱う場合、ほとんどの場合、データの計算は整数を加算または減算する単純な問題であり、同じ理由で午前 0 時からの秒であるため、ユリウス日を使用します。秒よりも細かい粒度の時間解像度が必要になることはめったにありません。
これらは両方とも 4 バイトの整数として格納でき、スペースが本当に狭い場合は、2106 年頃まで有効な符号なし整数として UNIX 時間 (1970 年 1 月 1 日からの秒数) に組み合わせることができます。
' 秒 (24 時間) = 86400
' Signed Integer max val = 2,147,483,647 - 68 年の秒を保持できます
' 符号なし整数の最大値 = 4,294,967,295 - 136 年の秒数を保持できます
MySQL 4.1 では、文字列以外のデータ値を、文字列形式との間で変換せずにネイティブ形式で送受信できるバイナリ プロトコルが導入されました。(非常に便利)
余談ですが、mysql_real_query() はステートメント文字列を操作するために strlen() を呼び出さないため、mysql_query() よりも高速です。
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html バイナリ プロトコルはサーバー側のプリペアド ステートメントをサポートし、データ値をネイティブ形式で送信できます。バイナリ プロトコルは、MySQL 4.1 の以前のリリース中にかなりの改訂が行われました。
IS_NUM() マクロを使用して、フィールドが数値型かどうかをテストできます。type 値を IS_NUM() に渡すと、フィールドが数値の場合に TRUE と評価されます。
注意すべきことの 1 つは、バイナリ データをエスケープする場合、通常のクエリ内で送信できることです。これは、暗号化されたパスワードやソルトされたパスワードなどの短いバイナリ文字列を挿入するための非常に簡単な方法です。
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 . 「slave_password」で識別されたslave_userに
#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
バイナリ ログ ファイルは以下を読み取る必要があります。
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
RESET MASTER ステートメントを使用してすべてのバイナリ ログ ファイルを削除するか、PURGE MASTER ステートメントを使用してそれらのサブセットを削除できます。
--result-file=binlog.txt TrustedFriend-bin.000030
http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html
http://www.koders.com/cpp/fid10666379322B54AD41AEB0E4100D87C8CDDF1D8C.aspx
http://souptonuts.sourceforge.net/readme_mysql.htm
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-effective-data-storage-mysql-part-1/
注意すべきことの 1 つは、CHAR と VARCHAR の両方を含む混合テーブルでは、mySQL が CHAR を VARCHAR に変更することです。
RecNum integer_type UNSIGNED NOT NULL AUTO_INCREMENT、PRIMARY KEY (RecNum)
MySQL は、標準 SQL および ISO 8601 仕様に従って、常に最初に年を付けて日付を表します。
一部の MySQl 機能をオフにすると、データ ファイルが小さくなり、アクセスが高速になります。例えば:
--datadir はデータ ディレクトリを指定し、
--skip-innodb は inno オプションをオフにして、10 ~ 20M 節約します
詳細はこちら http://dev.mysql.com/tech-resources/articles/mysql-c-api.html
第7章をダウンロード - 無料
InnoDB はトランザクショナルですが、それに伴うパフォーマンス オーバーヘッドがあります。私のプロジェクトの 90% には、MyISAM テーブルで十分であることがわかりました。非トランザクション セーフ テーブル (MyISAM) には独自の利点がいくつかあります。
トランザクションのオーバーヘッドはありません:
はるかに高速
より低いディスク容量要件
更新の実行に必要なメモリが少ない
各 MyISAM テーブルは、ディスク上の 3 つのファイルに格納されます。ファイルには、テーブル名で始まり、ファイルの種類を示す拡張子が付いた名前が付いています。.frm ファイルには、テーブル形式が格納されます。データ ファイルの拡張子は .MYD (MYData) です。インデックス ファイルの拡張子は .MYI (MYIndex) です。
これらのファイルは、時間のかかる MySQL 管理者のバックアップ機能を使用せずにそのまま保存場所にコピーできます (復元も同様です)。
秘訣は、これらのファイルのコピーを作成してから、テーブルを削除することです。ファイルを元に戻すと、MySQl はそれらを認識し、テーブル トラッキングを更新します。
バックアップ/復元が必要な場合は、
各テーブルにあるインデックスと主キーの数によっては、バックアップの復元または既存のダンプ ファイルからのインポートに時間がかかる場合があります。元のダンプ ファイルを次のように囲んで変更すると、このプロセスを大幅に高速化できます。
SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;
.. your dump file ..
SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;
リロードの速度を大幅に向上させるには、SQL コマンド SET AUTOCOMMIT = 0; を追加します。ダンプ ファイルの先頭に、COMMIT を追加します。コマンドを最後まで実行します。
デフォルトでは、自動コミットがオンになっています。つまり、ダンプ ファイル内のすべての挿入コマンドが個別のトランザクションとして扱われ、次のトランザクションが開始される前にディスクに書き込まれます。これらのコマンドを追加しないと、大規模なデータベースを InnoDB にリロードするのに何時間もかかることがあります...
MySQL テーブルの行の最大サイズは 65,535 バイトです
MySQL 5.0.3 以降での VARCHAR の有効な最大長 = 最大行サイズ (65,535 バイト)
VARCHAR 値は、格納時にパディングされません。末尾のスペースは、標準 SQL に準拠して、値が保存および取得されるときに保持されます。
MySQL の CHAR 値と VARCHAR 値は、末尾のスペースに関係なく比較されます。
CHAR を使用すると、レコード全体が固定サイズの場合にのみアクセスが高速化されます。つまり、可変サイズのオブジェクトを使用する場合は、それらすべてを可変サイズにすることもできます。VARCHAR も含むテーブルで CHAR を使用しても速度は向上しません。
255 文字の VARCHAR 制限は、MySQL 5.0.3 で 65535 文字に引き上げられました。
全文検索は、MyISAM テーブルでのみサポートされています。
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
BLOB 列には文字セットがなく、並べ替えと比較は列値のバイトの数値に基づいています
厳密な SQL モードが有効になっておらず、列の最大長を超える値を BLOB または TEXT 列に割り当てると、値は収まるように切り捨てられ、警告が生成されます。
厳格なモードを確認してください: SELECT @@global.sql_mode;
厳密モードをオフにします。
SET @@global.sql_mode= '';
SET @@global.sql_mode='MYSQL40'
または削除: sql-mode="STRICT_TRANS_TABLES,...
次の列を表示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()
現在のスレッドに挿入された最後の行の PK を取得します max(pkcolname) は、最後の PK 全体を取得します。
注: テーブルが空の場合、 max(pkcolname) は 1 を返します。 mysql_insert_id() は、ネイティブの MySQL C API 関数 mysql_insert_id() の戻り値の型を long 型 (PHP では int という名前) に変換します。
AUTO_INCREMENT カラムのカラム タイプが BIGINT の場合、mysql_insert_id() によって返される値は正しくありません。代わりに、SQL クエリで内部 MySQL SQL 関数 LAST_INSERT_ID() を使用します。
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
テーブルにデータを挿入しようとすると、エラーが発生することに注意してください。
Unknown column ‘the first bit of data what you want to put into the table‘ in ‘field list’
のようなものを使用して
INSERT INTO table (this, that) VALUES ($this, $that)
これは、テーブルに貼り付けようとしている値の周りにアポストロフィがないためです。したがって、コードを次のように変更する必要があります。
INSERT INTO table (this, that) VALUES ('$this', '$that')
`` は、値ではなく、MySQL フィールド、データベース、またはテーブルを定義するために使用されることに注意してください ;)
クエリ中にサーバーへの接続が失われました:
http://dev.mysql.com/doc/refman/5.1/en/gone-away.html
http://dev.mysql.com/doc/refman/5.1/en/packet-to-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
http://www.artfulsoftware.com/infotree/queries.php?&bw=1313
ボーナスを得るにはそれで十分だと思います...何時間にもわたる多くのプロジェクトの成果であり、優れた無料のデータベースがあります。主に MySQL を使用して、Windows プラットフォームでアプリケーション データ サーバーを開発しています。私が正さなければならなかった最悪の混乱は
これには、ここで説明した多くのトリックを使用して、テーブルを何か有用なものに処理するための一連のアプリケーションが必要でした。
これが驚くほど役に立ったと思ったら、投票して感謝の意を表してください。
www.coastrd.com で私の他の記事やホワイト ペーパーもチェックしてください。
MySQL のそれほど隠されていない機能の 1 つは、SQL に準拠することがあまり得意ではないということです。まあ、実際にはバグではありませんが、さらに落とし穴があります ... :-)
現在キャッシュにあるテーブルを確認するコマンド:
mysql> SHOW open TABLES FROM test;
+----------+-------+--------+-------------+
| DATABASE | TABLE | In_use | Name_locked |
+----------+-------+--------+-------------+
| test | a | 3 | 0 |
+----------+-------+--------+-------------+
1 row IN SET (0.00 sec)
( MySQL パフォーマンス ブログより)
誰が何をしているかを調べるコマンド:
mysql> show processlist;
show processlist;
+----+-------------+-----------------+------+---------+------+----------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------------+------+---------+------+----------------------------------+------------------+
| 1 | root | localhost:32893 | NULL | Sleep | 0 | | NULL |
| 5 | system user | | NULL | Connect | 98 | Waiting for master to send event | NULL |
| 6 | system user | | NULL | Connect | 5018 | Reading event from the relay log | NULL |
+-----+------+-----------+---------+---------+-------+-------+------------------+
3 rows in set (0.00 sec)
また、次の方法でプロセスを強制終了できます。
mysql>kill 5
私は特に、MySQL のinet_ntoa()
およびの組み込みサポートが気に入っていますinet_aton()
。これにより、テーブル内の IP アドレスの処理が非常に簡単になります (少なくとも、IPv4 アドレスのみである限り!)。
怠惰に作成されたあらゆる種類のカウンターが大好きですon duplicate key
(別名アップサート、マージ):
insert into occurances(word,count) values('foo',1),('bar',1)
on duplicate key cnt=cnt+1
1 つのクエリに多くの行を挿入し、各行の重複インデックスをすぐに処理できます。
繰り返しますが、隠れた機能ではありませんが、非常に便利です。
特徴
DDL を簡単に取得:
SHOW CREATE TABLE CountryLanguage
出力:
CountryLanguage | CREATE TABLE countrylanguage (
CountryCode char(3) NOT NULL DEFAULT '',
Language char(30) NOT NULL DEFAULT '',
IsOfficial enum('T','F') NOT NULL DEFAULT 'F',
Percentage float(4,1) NOT NULL DEFAULT '0.0',
PRIMARY KEY (CountryCode,Language)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
機能: GROUP_CONCAT() 集計関数 詳細ごとにその引数の連結文字列を作成し、それらをグループごとに連結して集計します。
例 1: シンプル
SELECT CountryCode
, GROUP_CONCAT(Language) AS List
FROM CountryLanguage
GROUP BY CountryCode
出力:
+-------------+------------------------------------+
| CountryCode | List |
+-------------+------------------------------------+
| ABW | Dutch,English,Papiamento,Spanish |
. ... . ... .
| ZWE | English,Ndebele,Nyanja,Shona |
+-------------+------------------------------------+
例 2: 複数の引数
SELECT CountryCode
, GROUP_CONCAT(
Language
, IF(IsOfficial='T', ' (Official)', '')
) AS List
FROM CountryLanguage
GROUP BY CountryCode
出力:
+-------------+---------------------------------------------+
| CountryCode | List |
+-------------+---------------------------------------------+
| ABW | Dutch (Official),English,Papiamento,Spanish |
. ... . ... .
| ZWE | English (Official),Ndebele,Nyanja,Shona |
+-------------+---------------------------------------------+
例 3: カスタム セパレータの使用
SELECT CountryCode
, GROUP_CONCAT(Language SEPARATOR ' and ') AS List
FROM CountryLanguage
GROUP BY CountryCode
出力:
+-------------+----------------------------------------------+
| CountryCode | List |
+-------------+----------------------------------------------+
| ABW | Dutch and English and Papiamento and Spanish |
. ... . ... .
| ZWE | English and Ndebele and Nyanja and Shona |
+-------------+----------------------------------------------+
例 4: リスト要素の順序を制御する
SELECT CountryCode
, GROUP_CONCAT(
Language
ORDER BY CASE IsOfficial WHEN 'T' THEN 1 ELSE 2 END DESC
, Language
) AS List
FROM CountryLanguage
GROUP BY CountryCode
出力:
+-------------+------------------------------------+
| CountryCode | List |
+-------------+------------------------------------+
| ABW | English,Papiamento,Spanish,Dutch, |
. ... . ... .
| ZWE | Ndebele,Nyanja,Shona,English |
+-------------+------------------------------------+
機能: 複数の式を持つ COUNT(DISTINCT )
COUNT(DISTINCT ...) 式で複数の式を使用して、組み合わせの数をカウントできます。
SELECT COUNT(DISTINCT CountryCode, Language) FROM CountryLanguage
機能/問題: GROUP BY リストに非集計式を含める必要はありません
ほとんどの RDBMS は、SQL92 準拠の GROUP BY を強制します。これは、SELECT リスト内のすべての非集計式を GROUP BY に含める必要があります。これらの RDBMS-es では、このステートメント:
SELECT Country.Code, Country.Continent, COUNT(CountryLanguage.Language)
FROM CountryLanguage
INNER JOIN Country
ON CountryLanguage.CountryCode = Country.Code
GROUP BY Country.Code
SELECT リストには、GROUP BY リストに表示されない集計されていない列 Country.Continent が含まれているため、無効です。これらの RDBMS では、GROUP BY リストを変更して読み取る必要があります。
GROUP BY Country.Code, Country.Continent
または、意味のない集計を Country.Continent に追加する必要があります。たとえば、
SELECT Country.Code, MAX(Country.Continent), COUNT(CountryLanguage.Language)
さて、問題は、論理的には、Country.Continent を集約することを要求するものは何もないということです。Country.Code は Country テーブルの主キーです。Country.Continent も Country テーブルの列であるため、定義上、主キー Country.Code に機能的に依存しています。したがって、Country.Continent には、個別の Country.Code ごとに 1 つの値が存在する必要があります。あなたがそれを理解するなら、それを集約すること(値は1つしかありません)も、それによってグループ化すること(すでにグループ化しているため、結果をより一意にしないため)も意味がないことに気付くよりもパック)
とにかく - MySQL では、集計されていない列を SELECT リストに含めることができます。それらを GROUP BY 句に追加する必要はありません。
これに関する落とし穴は、集計されていない列を使用した場合、MySQL が保護しないことです。したがって、次のようなクエリです。
SELECT Country.Code, COUNT(CountryLanguage.Language), CountryLanguage.Percentage
FROM CountryLanguage
INNER JOIN Country
ON CountryLanguage.CountryCode = Country.Code
GROUP BY Country.Code
問題なく実行されますが、CountryLanguage.Percentage 列には意味のないものが含まれます (つまり、すべての言語のパーセンテージのうち、パーセンテージに使用できる値の 1 つがランダムに、または少なくとも制御できない範囲で選択されます。
参照: Group By神話の暴言
クライアントの「ページャー」コマンド
たとえば、結果に 10,000 行があり、それらを表示したい場合 (これは、"less" および "tee" コマンドが使用可能であることを前提としています。これは通常、Linux では当てはまりますが、Windows YMMV ではそうです)。
pager less
select lots_of_stuff FROM tbl WHERE clause_which_matches_10k_rows;
そして、「より少ない」ファイルビューアでそれらを取得するので、それらをうまくページングしたり、検索したりできます.
また
pager tee myfile.txt
select a_few_things FROM tbl WHERE i_want_to_save_output_to_a_file;
便利にファイルに書き込みます。
隠れた機能ではありませんが、それでも便利です: http://mtop.sourceforge.net/
cmdline Mysq を使用している場合は、金切り声/感嘆符を使用してコマンド ラインを操作できます (Linux マシンの場合 - Windows で同等の効果があるかどうかは不明)。例えば:
\! cat file1.sql
file1.sql のコードが表示されます。ステートメントとクエリをファイルに保存するには、tee 機能を使用します。
\T filename
これをオフにするには、\t を使用します
最後に、既に保存したスクリプトを実行するには、「ソース ファイル名」を使用します。もちろん、コマンド ラインから mysql を起動するときにスクリプト名を指定するのが通常の代替手段です。
mysql -u root -p < case1.sql
それが誰かに役立つことを願っています!
編集:別のものを思い出しました-コマンドラインからmysqlを呼び出すときに、-tスイッチを使用して、出力がテーブル形式になるようにすることができます-いくつかのクエリでの真の恩恵(ただし、ここで他の場所で言及されているように\ Gでクエリを終了することもできます)この点で役立ちます)。さまざまなスイッチに関するその他のコマンド コマンド ライン ツール
並べ替えの順序を変更するきちんとした方法を見つけました (通常は Case を使用します...) 並べ替えの順序を変更したい場合 (おそらく、1、2、3、 4) Order by 句内でフィールド関数を使用できます。例えば
フィールド順(sort_field,1,4,3,2)
これはMySQL固有のものではないと思いますが、私にとっては啓発的です:
書く代わりに
WHERE (x.id > y.id) OR (x.id = y.id AND x.f2 > y.f2)
あなたはただ書くことができます
WHERE (x.id, x.f2) > (y.id, y.f2)
大規模および/または高トランザクションの InnoDb データベースで作業する場合は、「SHOW INNODB STATUS」Mysql Performance ブログを学び、理解してください。
組み込みのSQL プロファイラー。
mysqlsla - 非常に一般的に使用されるスロー クエリ ログ分析ツールの 1 つです。最後にスロー クエリ ログを展開してからの上位 10 件のワースト クエリを確認できます。また、BAD クエリが起動された回数と、サーバーでの合計時間もわかります。
実際に文書化されていますが、非常に厄介です: 誤った日付やその他の誤った入力の自動変換。
MySQL 5.0.2 より前のバージョンでは、MySQL は違法または不適切なデータ値を許容し、データ入力のためにそれらを正当な値に強制します。MySQL 5.0.2 以降では、これがデフォルトの動作のままですが、サーバー SQL モードを変更して、サーバーがそれらを拒否し、それらが発生したステートメントを中止するなど、より伝統的な不適切な値の処理を選択できます。
日付に関しては、MySQL が入力を近くの有効な日付に調整せず、代わりに0000-00-00
定義上無効であるとして保存する場合、「幸運」になることがあります。ただし、その場合でも、この値を黙って保存するのではなく、MySQL が失敗することを望んでいる場合があります。
InnoDBはデフォルトで、縮小しない1つのグローバルテーブルスペースにすべてのテーブルを格納します。
これを使用innodb_file_per_table
すると、テーブルまたはデータベースを削除したときに削除される個別のテーブルスペースに各テーブルが配置されます。
スペースを再利用するにはデータベースをダンプして復元する必要があるため、事前に計画してください。
日時列に空の文字列値""を挿入すると、MySQLは値を00/00/00000:00:00として保持します。null値を保存するOracleとは異なります。
大規模なデータセットと DATETIME フィールドを使用したベンチマーク中、このクエリを実行すると常に遅くなります。
SELECT * FROM mytable
WHERE date(date_colum) BETWEEN '2011-01-01' AND ''2011-03-03';
このアプローチより:
SELECT * FROM mytable
WHERE date_column BETWEEN '2011-01-01 00:00:00' AND '2011-03-03 23:59:59'