[解決済み] なぜ SQLAlchemy の count() は生のクエリよりずっと遅いのでしょうか?
2022-03-13 03:10:33
質問
MySQLデータベースでSQLAlchemyを使っていますが、あるテーブルの行数を数えたいと思っています(およそ300k)。SQLAlchemyは カウント 関数は、MySQL に直接同じクエリを書くのに比べて、実行に約 50 倍の時間がかかります。私は何か間違ったことをしているのでしょうか?
# this takes over 3 seconds to return
session.query(Segment).count()
しかし
SELECT COUNT(*) FROM segments;
+----------+
| COUNT(*) |
+----------+
| 281992 |
+----------+
1 row in set (0.07 sec)
速度の差は、テーブルの大きさに応じて大きくなります(100k行以下ではほとんど気になりません)。
更新
使用方法
session.query(Segment.id).count()
の代わりに
session.query(Segment).count()
は、トリックを実行し、スピードアップするようです。しかし、なぜ最初のクエリーが遅くなるのか、まだ不可解です。
解決方法は?
残念ながら MySQL はサブクエリをひどく、ひどくサポートしており、これは私たちに非常に悪い影響を及ぼしています。 そのため
SQLAlchemyのドキュメント
最適化されたクエリを実現するには
query(func.count(Segment.id))
:
この Query が返すであろう行の数を返します。
これにより、このQueryのSQLは以下のように生成されます。
SELECT count(1) AS count_1 FROM (
SELECT <rest of query follows...> ) AS anon_1
カウントするカラムを細かく制御したい場合。 サブクエリの使用やFROM句の制御、あるいは 他の集約関数と併用する場合は、func 式を使用します。 query()、すなわち。
from sqlalchemy import func
# count User records, without
# using a subquery.
session.query(func.count(User.id))
# return count of user "id" grouped
# by "name"
session.query(func.count(User.id)).\
group_by(User.name)
from sqlalchemy import distinct
# count distinct "name" values
session.query(func.count(distinct(User.name)))
関連
-
MySQLのNULLについて解説した記事
-
MySQLインストールチュートリアル(Linux版
-
MySQL XAが分散型トランザクションを実装する方法を1記事にまとめました。
-
[解決済み】DynamoDB : 提供されたキー要素がスキーマと一致しません。
-
[解決済み】ValueError: 値の長さがインデックスの長さと一致しない|Pandas DataFrame.unique()
-
mysql5.7のインストールと、無料・長期利用を目的としたNavicateの導入プロセスについて
-
Mysql がエラーを報告 オペランドには 1 つのカラムが含まれている必要があります。
-
[解決済み] utf8_general_ciとutf8_unicode_ciの違いは何ですか?
-
[解決済み] SQLAlchemy: flush() と commit() の違いは何ですか?
-
[解決済み] 発生したばかりのMySQLの警告を表示するにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
MySQLデータベース・インデックスの左端一致の原則
-
mysqlにおけるvarcharの日付比較とソートの実装
-
MySQLのWhereの使用方法について説明します。
-
MySQLのNULLについて解説した記事
-
MySQLデータベースで数百万件のデータを10秒間で挿入
-
SQLステートメントエラーです。オペランドには 1 つのカラムを含める必要があります [括弧を追加せずに複数のフィールドをクエリする
-
[解決済み] なぜ SQLAlchemy の count() は生のクエリよりずっと遅いのでしょうか?
-
[解決済み] KEYキーワードは何を意味するのか?
-
[解決済み] SQLでカラムに最大値を持つ行のみを選択する [重複]。
-
[解決済み] MySQLデータベースのテーブルのサイズを取得する方法は?