ホームページ  >  記事  >  データベース  >  Meituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?

Meituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?

Java后端技术全栈
Java后端技术全栈転載
2023-08-24 15:23:391121ブラウズ


インタビュアー: あなたはまだ鍵をよく理解していますね。

新人の私: (答えを表現するためにわずかに微笑みながら)

インタビュアー: MySQL を何年も使ってきましたが、決して忘れられない落とし穴は何ですか。

新人の私: バラバラが話し始めます (面接前にこの種の面接の質問を用意してあるので、水をかけておきます)

以下は私の実戦に基づいています経験 データベース開発の標準化された使用法をいくつかまとめ、6 つの「回避」でまとめました。

1. データベースでの計算を避ける

やってはいけない」という格言があります。つま先を滑らせてください 物事を考えること、それがナオグアジの責任です 」という言葉をデータベース開発で使用すると、データベースに苦手なことをさせないようにすることを意味します。 MySQL は数学的な演算や論理的な判断が苦手なので、データベース内での演算は避け、複雑な演算はプログラム側の CPU に移すことができます。

2. インデックス列に対する操作の実行を避ける

かつて、同僚から SQL ステートメントを見てほしいと頼まれたことがあります。 . フロントでのクエリは速いと言われていますが、SQLを取り出してデータベースで実行すると10分実行しても結果が出ません。 SQL を確認した後、最終的にビュー内のサブクエリを見つけました。このサブクエリの SQL テキストは次のとおりです:

## 以下SQL来源于网络
SELECT  acinv_07.id_item ,
        SUM(acinv_07.dec_endqty) dec_endqty
FROM    acinv_07
WHERE   acinv_07.fiscal_year * 100 + acinv_07.fiscal_period 
        = ( SELECT DISTINCT
                   ctlm1101.fiscal_year * 100 + ctlm1101.fiscal_period
                   FROM ctlm1101 WHERE flag_curr = 'Y'
                   AND id_oprcode = 'acinv'
                   AND acinv_07.id_wh = ctlm1101.id_table)
GROUP BY acinv_07.id_item

acinv_07 テーブルの列 fical_year と列 fical_period にはインデックスが付けられます。ただし、インデックス列に対して操作が実行されると、インデックスを作成できたはずの列に対してインデックスを使用できなくなります。そこで、SQL

## 以下SQL来源于网络
SELECT    id_item ,
                    SUM(dec_qty) dec_qty
          FROM      dpurreq_03
          GROUP BY  id_item
        ) a ,
        ( SELECT    a.id_item ,
                    SUM(a.dec_endqty) dec_endqty
          FROM      acinv_07 a ,
                    ( SELECT DISTINCT
                                ctlm1101.fiscal_year ,
                                ctlm1101.fiscal_period ,
                                id_table
                      FROM      ctlm1101
                      WHERE     flag_curr = 'Y'
                                AND id_oprcode = 'acinv'
                    ) b
          WHERE     a.fiscal_year = b.fiscal_year
                    AND a.fiscal_period = b.fiscal_period
                    AND a.id_wh = b.id_table
          GROUP BY  a.id_item

に書き換えて実行すると、4 秒ほどで結果が得られます。一般に、SQL を作成するときは、絶対に必要な場合を除き、インデックス列に対して計算を実行しないでください。

3. count(*) を避ける

ページング クエリを実行するとき、常に Select count(# を使用する人がいます) ##) はレコードの総数を取得します。実際、これは効率的なアプローチではありません。なぜなら、クエリはデータを取得するときに一度実行されており、select count() は同じステートメントによるクエリと同等だからです。 2 回実行すると、当然データベースのオーバーヘッドが大きくなりますので、データベースに付属する API やシステム変数を使用してこの作業を完了する必要があります。

4. NULL フィールドの使用を避ける

データベース テーブルのフィールドを設計するときは、全員が NULL フィールドを追加するように最善を尽くす必要があります。 .

NOT NULL デフォルト '。 NULL フィールドを使用すると、クエリの最適化が困難になる、NULL 列にインデックスを追加するには追加のスペースが必要になる、NULL を含む複合インデックスが無効になるなど、多くの悪影響が生じます。 次のケースを見てください:

数据初始化:
create table table1 (
    `id` INT (11) NOT NULL,
    `name` varchar(20) NOT NULL
)


create table table2 (
    `id` INT (11) NOT NULL,
    `name`  varchar(20)
)

insert into table1 values (4,"tianweichang"),(2,"zhangsan"),(3,"lisi")
insert into table2 values (1,"tianweichang"),(2, null)

(1) NOT IN サブクエリは、NULL 値がある場合に常に空の結果を返し、クエリはエラーを起こしやすいです

select name from table1 where name not in (select name from table2 where id!=1)

Meituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?


##(2) 列の値は空にすることができ、インデックスには null 値が格納されず、これらのレコードは結果に含まれません。セット。
select * from table2 where name != 'tianweichang'

Meituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?


select * from table2 where name != 'zhaoyun1'

Meituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?


(3)
concat

を使用してスプライスする場合、各フィールドは最初に null でないと判断する必要があります。そうでない場合、いずれかのフィールドが空である限り、スプライシング結果は null## になります。 #

select concat("1", null) from dual;

Meituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?


(4) 当计算count时候,name为null 的不会计入统计

select count(name) from table2;

Meituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?


5、避免select

  • 使用select *可能会返回不使用的列的数据。它在MySQL数据库服务器和应用程序之间产生不必要的I/O磁盘和网络流量。
  • 如果明确指定列,则结果集更可预测并且更易于管理。想象一下,当您使用select *并且有人通过添加更多列来更改表格数据时,将会得到一个与预期不同的结果集。
  • 使用select *可能会将敏感信息暴露给未经授权的用户。

6、避免在数据库里存图片

图片确实是可以存储到数据库里的,例如通过二进制流将图片存到数据库中。

但是,强烈不建议把图片存储到数据库中!!!!首先对数据库的读/写的速度永远都赶不上文件系统处理的速度,其次数据库备份变的巨大,越来越耗时间,最后对文件的访问需要穿越你的应用层和数据库层。

以上がMeituan インタビュー: MySQL を使用しているときに遭遇した落とし穴は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はJava后端技术全栈で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。