MySQLの隠された機能


101

私は長年Microsoft SQL Server使用してきましたが、WebアプリケーションでMySQLを使用し始めたばかりで、知識に飢えています。

「隠された機能」に関する長い質問を続けるために、MySQLの隠された、または便利な機能を知りたいと思います。これにより、このオープンソースデータベースの知識が向上することが期待されます。

回答:


161

あなたが賞金を上げたので、私は私の勝った秘密を共有します...

一般に、今日調整したすべてのSQLでは、サブクエリを使用する必要がありました。Oracleデータベースの世界から来たので、当然のこととしてMySQLで同じように機能しませんでした。また、MySQLチューニングについて読んだところ、MySQLはクエリの最適化に関してOracleに遅れをとっていると結論づけました。

ほとんどのB2Cアプリケーションに必要な単純なクエリはMySQLで正常に機能する可能性がありますが、インテリジェンスレポートに必要なクエリの集約レポートタイプのほとんどは、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がすぐに大きくならないまで値を増やします。

主キー:

テーブルごとにAUTO_INCREMENT列は1つだけ存在でき、インデックスを作成する必要があり、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 = value;

特に指定がない限り、値は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つを使用する場合は、注意が必要です。WHEREUNIX_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で日時をUNIXタイムスタンプに変換する場合:
そして24時間をそれに追加します:そして、それを
日時に変換して、魔法のように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です。

日付を使用する場合、データ計算は整数を追加またはサブトレースするという単純な問題であり、同じ理由で真夜中からの秒数なので、ほとんどの場合、ジュリアンの日付を優先します。数秒よりも細かい粒度の時間応答が必要になることはまれです。

これらは両方とも4バイト整数として格納できます。スペースが非常に狭い場合は、UNIX時間(エポック1/1/1970からの秒数)に符号なし整数として組み合わせることができます。これは2106前後まで有効です。

'24時間での秒= 86400

'符号付き整数の最大値= 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()マクロを使用して、フィールドに数値タイプがあるかどうかをテストできます。タイプ値をIS_NUM()に渡し、フィールドが数値の場合はTRUEと評価します。

もう一つ注意すべきは、バイナリデータがあることであるCANあなたはそれを脱出し、MySQLが必要と覚えていれば、通常のクエリ内で送信することが唯一のバックスラッシュと引用符をエスケープすること。したがって、これは、たとえば暗号化/ソルトされたパスワードなどの短いバイナリ文字列を挿入するための本当に簡単な方法です。

マスターサーバー:

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

UDF関数

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-efficient-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はトランザクション対応ですが、それに伴うパフォーマンスオーバーヘッドがあります。MyISAMテーブルはプロジェクトの90%で十分であることがわかりました。非トランザクションセーフテーブル(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を使用しても速度は向上しません。

MySQL 5.0.3以降、255文字のVARCHAR制限は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 my(namecount)AS virtualcolumnFROM 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を返します。

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

クエリのチューニング

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

まあそれは私が思うボーナスを稼ぐのに十分なはずです...素晴らしい無料のデータベースを備えた多くの時間と多くのプロジェクトの成果。主にMySQLを使用して、Windowsプラットフォームでアプリケーションデータサーバーを開発しています。私が矯正しなければならなかった最悪の混乱は

究極のMySQLレガシーデータベースの悪夢

これには、ここで説明した多くのトリックを使用して、テーブルを処理して有用なものにする一連のアプリケーションが必要でした。

これが驚くほど役立つとわかった場合は、投票して感謝の意を表してください。

また、www.coastrd.comで他の記事やホワイトペーパーを確認してください。


22

MySQLのそれほど隠されていない機能の1つは、SQLに準拠するのがあまり得意ではないことです。まあ、実際にはバグではありませんが、より多くの落とし穴 ... :-)


MSSQLからMySQLに移行するときに、このリストが価値があることを他の人に知らせます。乾杯マット。
GateKiller 2008

それらの落とし穴の多くは、以前のバージョンのMySQLからのものです。
jmucchiello 2008

1つは、タイムスタンプフィールドにNULL値を入れることができるとは思いません。
マット

3
MySQLは他の多くのデータベースよりもSQLに準拠しているという点で特に劣っていません。SQLのまともなサブセットに固執している限り、一般に問題点を回避できます。Oracleの悪名高いNULL空文字列。
ボビンス2009年

1
いくつかの問題を無効にすることができますSET SESSION sql_mode='ANSI';
Kornel

21

現在キャッシュにあるテーブルを見つけるコマンド:

mysql> SHOW open TABLES FROM test;
+----------+-------+--------+-------------+
| DATABASE | TABLE | In_use | Name_locked |
+----------+-------+--------+-------------+
| test     | a     |      3 |           0 |
+----------+-------+--------+-------------+
1 row IN SET (0.00 sec)

MySQLパフォーマンスブログから)


15

誰が何をしているかを調べるコマンド:

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 

5
クエリを切り捨てない場合は、SHOW FULL PROCESSLISTも使用します。
グレッグ

11

私は特にMySQLのビルトインサポートなどinet_ntoa()inet_aton()。テーブル内のIPアドレスの処理が非常に簡単になります(少なくともIPv4アドレスのみである限り)。


2
PostgreSQLには非常に素晴らしいinetタイプがあり、ipv4とipv6を非常に巧妙に処理します:-)
mat

私も以前は気に入っていましたが、まったく使わなくてもよいのです。Postgresの場合は+1。
Kornel、2011年

11

私は愛してる on duplicate key怠惰に作成されたあらゆる種類のカウンターが(別名、アップサート、マージ)。

insert into occurances(word,count) values('foo',1),('bar',1) 
  on duplicate key cnt=cnt+1

1つのクエリに多数の行を挿入し、各行の重複インデックスをすぐに処理できます。


10

繰り返しになりますが、隠された機能ではありませんが、非常に便利です。

特徴

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-esは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-esでは、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つの値しかありません)、それをグループ化することは意味がないことに気づきます(すでにグループ化しているため、結果がより一意になるわけではないため) pk)

とにかく-MySQLでは、GROUP BY句に列を追加する必要なしに、SELECTリストに非集計列を含めることができます。

これの問題は、非集計列を使用した場合に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で宣言されていない列を許可することは、Oracleが提供する機能のうち、私が最も気に入っていない機能の1つです。Oracleに慣れている場合、これは大きな問題です。クエリを実行するだけで結果は正しく表示されますが、思ったとおりに動作していないことがわかります。
mbafford '25

7

クライアントの「ページャー」コマンド

たとえば、結果に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;

便利にファイルに書き込みます。


残念ながら、ウィンドウの下では、「少ない」と「ティー」が存在する場合でも、ページャーオプション自体はサポートされていません。とにかく簡単ではない
ベリーTsakala

6

あなたが面白いと思うかもしれないいくつかのもの:

<query>\G -- \G in the CLI instead of the ; will show one column per row
explain <query>; -- this will show the execution plan for the query


3

ここに私のヒントのいくつかがあります-私は私のブログでそれらについてブログに書いています(リンク

  1. 変数を宣言するときに「@」記号を使用する必要はありません。
  2. ステートメントの終わりを区切るには、区切り文字(デフォルトは ';')を使用する必要があります- リンク
  3. MS-SQL 2005とmySQLの間でデータを移動しようとする場合、いくつかのフープがあります- リンク
  4. mySQLで大文字と小文字を区別する一致を行う- リンク


3

cmdline Mysqを使用している場合は、shriek / exclamationマークを使用して、コマンドライン(Linuxマシンでは、Windowsに同等の効果があるかどうか不明)を操作できます。例えば:

\! cat file1.sql

file1.sqlのコードが表示されます。ステートメントとクエリをファイルに保存するには、ティー機能を使用します

\T filename

これをオフにするには、\ t

最後に、既に保存したスクリプトを実行するには、「ソースファイル名」を使用します。もちろん、通常の代替方法は、コマンドラインからmysqlを起動するときにスクリプト名を指定することです。

    mysql -u root -p < case1.sql

それが誰かに役立つことを願っています!

編集:ちょうど別のことを思い出した-コマンドラインからmysqlを呼び出すときに-tスイッチを使用して出力をテーブル形式にすることができます-いくつかのクエリを含む実際の恩恵(もちろん、他の場所で言及されているように\ Gでクエリを終了することもできます)この点で役立ちます)。さまざまなスイッチの詳細コマンドラインツールの詳細

並べ替えの順序を変更するためのきちんとした方法を見つけた(通常はCaseを使用...)並べ替えの順序を変更したい場合(おそらく1、2、3ではなく1、4、3、2で並べ替える) 4)Order by句内でフィールド関数を使用できます。例えば

フィールドで並べ替え(sort_field、1,4,3,2)


3

これは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)

それは本当にクールですが、これにはいくつかのユースケースがありますか?
mangoDrunk 2011年

特定のレコードよりも大きいすべてのレコードを検索するのに役立ちます。
ファンティウス

2

mysqlsla-非常に一般的に使用されているスロークエリログ分析ツールの1つ。uが低速のクエリログを最後にロールアウトしてから、ワーストクエリのトップ10を確認できます。また、BADクエリが発生した回数と、サーバーでかかった合計時間もわかります。


2

実際に文書化されていますが、非常に煩わしいです。日付が正しくないなど、入力が正しくない場合の自動変換。

MySQL 5.0.2より前では、MySQLは違法または不適切なデータ値を許容し、データ入力のためにそれらを正当な値に強制します。MySQL 5.0.2以降では、これがデフォルトの動作のままですが、サーバーのSQLモードを変更して、サーバーがそれらを拒否して発生したステートメントを中止するように、従来の不良値の処理を選択できます。

日付に関して:MySQLが入力を近くの有効な日付に調整せず0000-00-00、定義上無効なものとして格納する場合、「幸運」になることがあります。ただし、それでも、この値を自動的に保存するのではなく、MySQLが失敗するようにしたい場合があります。



1

InnoDBはデフォルトで、縮小されることのない 1つのグローバルテーブルスペースにすべてのテーブルを格納します。

innodb_file_per_tablewhichを使用すると、テーブルまたはデータベースを削除したときに削除される個別のテーブルスペースに各テーブルが配置されます。

それ以外の場合は、スペースを再利用するためにデータベースをダンプおよび復元する必要があるため、これを前もって計画してください。

テーブルごとのテーブルスペースの使用


1

日時列に空の文字列値 ""を挿入すると、MySQLは値を00/00/0000 00:00:00として保持します。null値を保存するOracleとは異なり。


1

大きなデータセットと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'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.