質問: FOO) ) SELECT COUNT(*) FROM s2 WHERE mol @> BAR ``` **WITHを用いた改善案のSQL文のEXPLAIN ANALYZE実行結果** ![WITHを用いた改善案のSQL文のEXPLAIN ANALYZE実行結果](https://teratail.storage.googleapis.com/uploads/contributed_images/a4c743ff09469ce16f29d0ace72f3b77.png) 今後の勉強のためにWITHを用いないSQL文で期待どおりに動くようにするためにはどうすればよいかアドバイスいただけたら幸いです。 @>というcartridge特有の機能が一番初めに実行される仕様となっているのでしょうか? また、インデックスを貼るなど以外のより高速にするためのアドバイスが有ればそちらも合わせていただけたら幸いです。 よろしくお願いします。 --- 追記 ご助言いただいたようにquery_idにインデックスを追加し、NATURA JOINをINに変更したSQL文のEXPLAIN ANALYZE実行結果 ![改善案ver2SQL文のEXPLAIN ANALYZE実行結果](https://teratail.storage.googleapis.com/uploads/contributed_images/dd78ede48ecfc5300fbe2865f9311acc.png) さらにご助言いただいたの結果はエラーとなりました。 ![イメージ説明](https://teratail.storage.googleapis.com/uploads/contributed_images/0c23d3ba793ea47ca8fe4812a10702a6.png) そこで、andでつないでみましたところ動きました。 ![イメージ説明](https://teratail.storage.googleapis.com/uploads/contributed_images/61bbaec09bde7d7e67480d094677d433.png)](6991aa282d69b7bc8b7fa9fd6fb26204.png)
回答: 「改善案」とされる2番目のSQLの実行計画(画像では1番目)は単純に1番目のSQLの実行計画(画像では2番目)に`substructures`テーブルのサブクエリの結果のJOINが結合されただけに見えますね。`substructures`の検索コストが元のクエリのコストよりも大きいので、絞込に使う意味はないですし、そうすると無意味にコストを増やしているだけになっています。 > > 二度部分構造検索を行ってしまっており > > > と書かれていますが、この点に違いはないように見えます。 3番目が意図通りと書かれていますが、コスト的には一番悪くなっています。 とりあえず大きな問題は、`substructures`の検索が遅すぎることです。実行計画を見る限りではこれはおそらく`query_id`にインデックスを張れば解決するとおもいます。 あとはサブクエリを結合してるのが何となくですが気持ち悪いです。結合ではなくINで検索するとか、サブクエリを使わずにJOINするとか、いろいろ試して実行計画確認してみてください > > @>というcartridge特有の機能が一番初めに実行される仕様となっているのでしょうか? > > > 外部のライブラリによって提供される演算子については、ライブラリ側でコストが過小や過大に設定されているためにコスト計算がおかしくなり不効率な実行計画が選択される事例があるようです。が、実行計画見る限りではその例には当てはまらないような気がします。 -- 追記されたSQLですが、二重になってるサブクエリのうち内側はともかく外側は意味不明です。 ``` SELECT * FROM compounds WHERE compounds_id IN (SELECT ...) AND mol @> ... ``` でよいでしょう。