SELECT Distinct org.id_name,org.id_region,org.id_inn,org.id_kpp,org.id_username, agreements.id_agr_code,
agreements.id_crat, agreements.id_project_name, agreements.comment, agreements.comment2, agreements.id_factor, agreements.id_name,
month1.id_date_money,month1.id_done,month2.id_date_money,month2.id_done,month3.id_date_money,month3.id_done,month4.id_date_money,
month4.id_done,month5.id_date_money,month5.id_done,month6.id_date_money,month6.id_done FROM agreements
inner join org on (org.id_org=agreements.id_org)
LEFT OUTER JOIN money as month1 ON (agreements.id_agr = month1.id_dogovor) and (month1.id_date_money is NULL OR month1.id_date_money=:Month1)
LEFT OUTER JOIN money as month2 ON (agreements.id_agr = month2.id_dogovor) and (month2.id_date_money is NULL OR month2.id_date_money=:Month2)
LEFT OUTER JOIN money as month3 ON (agreements.id_agr = month3.id_dogovor) and (month3.id_date_money is NULL OR month3.id_date_money=:Month3)
LEFT OUTER JOIN money as month4 ON (agreements.id_agr = month4.id_dogovor) and (month4.id_date_money is NULL OR month4.id_date_money=:Month4)
LEFT OUTER JOIN money as month5 ON (agreements.id_agr = month5.id_dogovor) and (month5.id_date_money is NULL OR month5.id_date_money=:Month5)
LEFT OUTER JOIN money as month6 ON (agreements.id_agr = month6.id_dogovor) and (month6.id_date_money is NULL OR month6.id_date_money=:Month6)
where agreements.id_old=:Archive
and case when :region is null then org.id_region=org.id_region else FIND_IN_SET(org.id_region, :region) end
and case when :users is null then org.id_user=org.id_user else FIND_IN_SET(org.id_user, :users) end
and case when :agrtype is null then agreements.id_type=agreements.id_type else FIND_IN_SET(agreements.id_type, :agrtype) end
and case when :agrproject is null then agreements.id_project_name=agreements.id_project_name else FIND_IN_SET(agreements.id_project_name, :agrproject) end
ORDER BY org.id_name
このSQL文は完了するまでに非常に多くの時間を要し、いくつかの時点では、ルートとなる多くの接続を作成し、 "コピーするtmp_table "エラーメッセージに「BDへの接続が多すぎます」と表示されます。SQLステートメントは多くの接続を作成し、データベースをハングします
これはFIND_IN_SETのためだと思いますが、わかりません。このSQLを書き直して、より速く実行し、すべての接続を作成しないようにする方法を見つけることはできません(最大になるまでそれを作成し続けます)。
アイデアは、どの組織のどの契約が定義された月に支払いを受けているかを示しています。領域のフィルタは01,05,09,23,26,91およびe.t.cという数字になり、ユーザのフィルタはuser_idの整数になります。 agrtypesのフィルタは文字列内にあり、agrprojectsも文字列内にあります。 ID_oldはブール値のフラグです。 ID_agr、ID_Dogovor、およびid_orgは主キーIntegerです。
あなたは、データベースを正規化していないとしてコラムで区切られたリストを代わりに列に入れることに決めたので、速度に対しても決定しました。どのレコードに特定の領域が含まれているかを知るためには、すべてのレコードを読み取ってチェックする必要がありますが、org_regionテーブルではDBMSはおそらくインデックスを使用します。 –