Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1XGvNi-0001n6-Hv for pgsql-sql@arkaria.postgresql.org; Mon, 11 Aug 2014 19:35:46 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.80) (envelope-from ) id 1XGvNi-0006dj-03 for pgsql-sql@arkaria.postgresql.org; Mon, 11 Aug 2014 19:35:46 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1XGvNg-0006au-0v for pgsql-sql@postgresql.org; Mon, 11 Aug 2014 19:35:44 +0000 Received: from mail-pd0-x235.google.com ([2607:f8b0:400e:c02::235]) by makus.postgresql.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1XGvNc-0001mU-Ba for pgsql-sql@postgresql.org; Mon, 11 Aug 2014 19:35:42 +0000 Received: by mail-pd0-f181.google.com with SMTP id g10so11303274pdj.12 for ; Mon, 11 Aug 2014 12:35:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=CX3lmTKMozAoh6dd4AY55nj8Sf++3GzDZjOuWYQmwfE=; b=CtrgemjJYnDNz4X/DEjHg4VNFdg12hpLWFawNf1zzRSk5w3xT2i1Jb47VHDIBTKvuQ /rSoh/ag/E+QWsjT9tT4SQPpEcHohLeCdsthQdhqYQoImotzkXF88zUPYccOLAQB3FhP PtZB1WnKZiqyMNf6f0DQYXT2dU8QBHscruGSl2ovYR4xxnQ9zH1XhezgpMWKDlGpfV55 9zEIcWNhE1e7I0+QfCwsyE799kILheJdTd+ti7IOT9+wOP79Mjr4hhGKZ0Vyo6iVMoab VLMc0zx6n+057EGnHg1qJJInECaFsYklaqdUkbkixz0O9e2X13KIOtlGYFwwnCTsR3rr /XGw== X-Received: by 10.70.126.229 with SMTP id nb5mr27988914pdb.18.1407785738468; Mon, 11 Aug 2014 12:35:38 -0700 (PDT) MIME-Version: 1.0 Received: by 10.70.131.130 with HTTP; Mon, 11 Aug 2014 12:34:57 -0700 (PDT) In-Reply-To: References: From: Pavel Stehule Date: Mon, 11 Aug 2014 21:34:57 +0200 Message-ID: Subject: Re: How to optimize WHERE column_a IS NOT NULL OR column_b = 'value' To: Andreas Joseph Krogh Cc: postgres list Content-Type: multipart/related; boundary=001a11c34f7edc99de05005fa819 X-Pg-Spam-Score: -2.0 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org --001a11c34f7edc99de05005fa819 Content-Type: multipart/alternative; boundary=001a11c34f7edc99da05005fa818 --001a11c34f7edc99da05005fa818 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi 2014-08-11 18:01 GMT+02:00 Andreas Joseph Krogh : > Hi folks, > > I have the following schema (simplified for this example). > > create table folder(id integer primary key, name varchar not null); > > create table document(id serial primary key, name varchar not null, > owner_id integer not null, folder_id integer references folder(id)); > create index document_owner_idx ON document(owner_id); > create index document_folder_idx ON document(folder_id); > > insert into folder(id, name) values(1, 'Folder A'); > insert into folder(id, name) values(2, 'Folder B'); > insert into document(name, owner_id, folder_id) values('Document A', 1, > 1); > insert into document(name, owner_id, folder_id) values('Document B', 1, > NULL); > insert into document(name, owner_id, folder_id) values('Document C', 2, > 2); > insert into document(name, owner_id, folder_id) values('Document D', 2, > NULL); > > select f.id, f.name, doc.id, doc.owner_id, doc.name > FROM document doc left outer join folder f ON doc.folder_id =3D f.id > WHERE doc.folder_id is not null OR doc.owner_id =3D 1; > > QUERY PLAN > > -------------------------------------------------------------------------= ---------------------------------------------------- > Nested Loop Left Join (cost=3D0.15..13.77 rows=3D4 width=3D76) (actual > time=3D0.031..0.045 rows=3D3 loops=3D1) > -> Seq Scan on document doc (cost=3D0.00..1.05 rows=3D4 width=3D44) = (actual > time=3D0.012..0.018 rows=3D3 loops=3D1) > Filter: ((folder_id IS NOT NULL) OR (owner_id =3D 1)) > Rows Removed by Filter: 1 > -> Index Scan using folder_pkey on folder f (cost=3D0.15..3.17 rows= =3D1 > width=3D36) (actual time=3D0.005..0.006 rows=3D1 loops=3D3) > Index Cond: (doc.folder_id =3D id) > Planning time: 0.267 ms > Execution time: 0.094 ms > (8 rows) > > > Is the a way to write a query which uses an index efficiently for such a > schema? > > I'd like to eliminate the Filter: ((folder_id IS NOT NULL) OR (owner_id = =3D > 1)) and rather have "index cond" insted, is that possible? > your example is partially broken - ANALYZE and hashjoin and seqscan penalization are missing - index scan is not used due too small table sizes I tested 9.5, probably same as 9.4 and there indexes are used postgres=3D# set enable_hashjoin to off; SET Time: 0.473 ms postgres=3D# set enable_seqscan to off; SET Time: 0.904 ms postgres=3D# explain select f.id, f.name, doc.id, doc.owner_id, doc.name FROM document doc left outer join folder f ON doc.folder_id =3D f.id WHERE doc.folder_id is not null OR doc.owner_id =3D 1; QUERY PLAN =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Merge Left Join (cost=3D0.26..24.38 rows=3D3 width=3D32) Merge Cond: (doc.folder_id =3D f.id) -> Index Scan using document_folder_idx on document doc (cost=3D0.13..12.20 rows=3D3 width=3D23) Filter: ((folder_id IS NOT NULL) OR (owner_id =3D 1)) -> Index Scan using folder_pkey on folder f (cost=3D0.13..12.16 rows= =3D2 width=3D13) Planning time: 0.663 ms (6 rows) default 9.2, 9.3, ... postgres=3D# explain select f.id, f.name, doc.id, doc.owner_id, doc.name FROM document doc left outer join folder f ON doc.folder_id =3D f.id WHERE doc.folder_id is not null OR doc.owner_id =3D 1; QUERY PLAN =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80 Hash Left Join (cost=3D1.04..2.12 rows=3D3 width=3D32) Hash Cond: (doc.folder_id =3D f.id) -> Seq Scan on document doc (cost=3D0.00..1.05 rows=3D3 width=3D23) Filter: ((folder_id IS NOT NULL) OR (owner_id =3D 1)) -> Hash (cost=3D1.02..1.02 rows=3D2 width=3D13) -> Seq Scan on folder f (cost=3D0.00..1.02 rows=3D2 width=3D13) (6 rows) and 9.2 after hashjoin and indexscan penalization postgres=3D# explain select f.id, f.name, doc.id, doc.owner_id, doc.name FROM document doc left outer join folder f ON doc.folder_id =3D f.id WHERE doc.folder_id is not null OR doc.owner_id =3D 1; QUERY PLAN =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Merge Left Join (cost=3D0.00..24.62 rows=3D3 width=3D32) Merge Cond: (doc.folder_id =3D f.id) -> Index Scan using document_folder_idx on document doc (cost=3D0.00..12.32 rows=3D3 width=3D23) Filter: ((folder_id IS NOT NULL) OR (owner_id =3D 1)) -> Index Scan using folder_pkey on folder f (cost=3D0.00..12.28 rows= =3D2 width=3D13) (5 rows) Time: 2.258 ms What is your PostgreSQL? Regards Pavel P.S. ten years ago I had a similar issue - "OR" predikates can be replaced by UNION you can try: SELECT * FROM (SELECT * FROM doc WHERE folder_id IS NOT NULL UNION SELECT * FROM doc WHERE owner_id =3D 1) s LEFT JOIN folder ON s.folder_id =3D folder.id or some similar magic select f.id, f.name, doc.id, doc.owner_id, doc.name FROM document doc left outer join folder f ON doc.folder_id =3D f.id WHERE doc.folder_id is not null OR doc.owner_id =3D 1; > > -- > *Andreas Joseph Krogh* > CTO / Partner - Visena AS > Mobile: +47 909 56 963 > andreas@visena.com > www.visena.com > > --001a11c34f7edc99da05005fa818 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+SGk8YnI+PGRpdiBjbGFzcz0iZ21haWxfZXh0cmEiPjxicj48YnI+PGRp diBjbGFzcz0iZ21haWxfcXVvdGUiPjIwMTQtMDgtMTEgMTg6MDEgR01UKzAyOjAwIEFuZHJlYXMg Sm9zZXBoIEtyb2doIDxzcGFuIGRpcj0ibHRyIj4mbHQ7PGEgaHJlZj0ibWFpbHRvOmFuZHJlYXNA dmlzZW5hLmNvbSIgdGFyZ2V0PSJfYmxhbmsiPmFuZHJlYXNAdmlzZW5hLmNvbTwvYT4mZ3Q7PC9z cGFuPjo8YnI+DQoNCjxibG9ja3F1b3RlIGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdp bjowcHggMHB4IDBweCAwLjhleDtib3JkZXItbGVmdDoxcHggc29saWQgcmdiKDIwNCwyMDQsMjA0 KTtwYWRkaW5nLWxlZnQ6MWV4Ij48ZGl2PkhpIGZvbGtzLDwvZGl2Pg0KDQo8ZGl2PsKgPC9kaXY+ DQoNCjxkaXY+SSBoYXZlIHRoZSBmb2xsb3dpbmcgc2NoZW1hIChzaW1wbGlmaWVkIGZvciB0aGlz IGV4YW1wbGUpLjwvZGl2Pg0KDQo8ZGl2PsKgPC9kaXY+DQoNCjxkaXY+Y3JlYXRlIHRhYmxlIGZv bGRlcihpZCBpbnRlZ2VyIHByaW1hcnkga2V5LCBuYW1lIHZhcmNoYXIgbm90IG51bGwpOzwvZGl2 Pg0KDQo8ZGl2PsKgPC9kaXY+DQoNCjxkaXY+Y3JlYXRlIHRhYmxlIGRvY3VtZW50KGlkIHNlcmlh bCBwcmltYXJ5IGtleSwgbmFtZSB2YXJjaGFyIG5vdCBudWxsLCBvd25lcl9pZCBpbnRlZ2VyIG5v dCBudWxsLCBmb2xkZXJfaWQgaW50ZWdlciByZWZlcmVuY2VzIGZvbGRlcihpZCkpOzwvZGl2Pg0K DQo8ZGl2PmNyZWF0ZSBpbmRleCBkb2N1bWVudF9vd25lcl9pZHggT04gZG9jdW1lbnQob3duZXJf aWQpOzwvZGl2Pg0KDQo8ZGl2PmNyZWF0ZSBpbmRleCBkb2N1bWVudF9mb2xkZXJfaWR4IE9OIGRv Y3VtZW50KGZvbGRlcl9pZCk7PC9kaXY+DQoNCjxkaXY+wqA8L2Rpdj4NCg0KPGRpdj5pbnNlcnQg aW50byBmb2xkZXIoaWQsIG5hbWUpIHZhbHVlcygxLCAmIzM5O0ZvbGRlciBBJiMzOTspOzwvZGl2 Pg0KDQo8ZGl2Pmluc2VydCBpbnRvIGZvbGRlcihpZCwgbmFtZSkgdmFsdWVzKDIsICYjMzk7Rm9s ZGVyIEImIzM5Oyk7PC9kaXY+DQoNCjxkaXY+aW5zZXJ0IGludG8gZG9jdW1lbnQobmFtZSwgb3du ZXJfaWQsIGZvbGRlcl9pZCkgdmFsdWVzKCYjMzk7RG9jdW1lbnQgQSYjMzk7LMKgIDEsIDEpOzwv ZGl2Pg0KDQo8ZGl2Pmluc2VydCBpbnRvIGRvY3VtZW50KG5hbWUsIG93bmVyX2lkLCBmb2xkZXJf aWQpIHZhbHVlcygmIzM5O0RvY3VtZW50IEImIzM5OyzCoCAxLCBOVUxMKTs8L2Rpdj4NCg0KPGRp dj5pbnNlcnQgaW50byBkb2N1bWVudChuYW1lLCBvd25lcl9pZCwgZm9sZGVyX2lkKSB2YWx1ZXMo JiMzOTtEb2N1bWVudCBDJiMzOTsswqAgMiwgMik7PC9kaXY+DQoNCjxkaXY+aW5zZXJ0IGludG8g ZG9jdW1lbnQobmFtZSwgb3duZXJfaWQsIGZvbGRlcl9pZCkgdmFsdWVzKCYjMzk7RG9jdW1lbnQg RCYjMzk7LMKgIDIsIE5VTEwpOzwvZGl2Pg0KDQo8ZGl2PsKgPC9kaXY+DQoNCjxkaXY+c2VsZWN0 IDxhIGhyZWY9Imh0dHA6Ly9mLmlkIiB0YXJnZXQ9Il9ibGFuayI+Zi5pZDwvYT4sIDxhIGhyZWY9 Imh0dHA6Ly9mLm5hbWUiIHRhcmdldD0iX2JsYW5rIj5mLm5hbWU8L2E+LCA8YSBocmVmPSJodHRw Oi8vZG9jLmlkIiB0YXJnZXQ9Il9ibGFuayI+ZG9jLmlkPC9hPiwgZG9jLm93bmVyX2lkLCA8YSBo cmVmPSJodHRwOi8vZG9jLm5hbWUiIHRhcmdldD0iX2JsYW5rIj5kb2MubmFtZTwvYT48L2Rpdj4N Cg0KDQoNCjxkaXY+RlJPTSBkb2N1bWVudCBkb2MgbGVmdCBvdXRlciBqb2luIGZvbGRlciBmIE9O IGRvYy5mb2xkZXJfaWQgPSA8YSBocmVmPSJodHRwOi8vZi5pZCIgdGFyZ2V0PSJfYmxhbmsiPmYu aWQ8L2E+PC9kaXY+DQoNCjxkaXY+V0hFUkUgZG9jLmZvbGRlcl9pZCBpcyBub3QgbnVsbCBPUiBk b2Mub3duZXJfaWQgPSAxOzwvZGl2Pg0KDQo8ZGl2PsKgPC9kaXY+DQoNCjxkaXY+DQo8ZGl2PsKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgUVVF UlkgUExBTjxicj4NCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPGJyPg0KwqBOZXN0ZWQgTG9vcCBMZWZ0IEpvaW7CoCAo Y29zdD0wLjE1Li4xMy43NyByb3dzPTQgd2lkdGg9NzYpIChhY3R1YWwgdGltZT0wLjAzMS4uMC4w NDUgcm93cz0zIGxvb3BzPTEpPGJyPg0KwqDCoCAtJmd0O8KgIFNlcSBTY2FuIG9uIGRvY3VtZW50 IGRvY8KgIChjb3N0PTAuMDAuLjEuMDUgcm93cz00IHdpZHRoPTQ0KSAoYWN0dWFsIHRpbWU9MC4w MTIuLjAuMDE4IHJvd3M9MyBsb29wcz0xKTxicj4NCsKgwqDCoMKgwqDCoMKgwqAgRmlsdGVyOiAo KGZvbGRlcl9pZCBJUyBOT1QgTlVMTCkgT1IgKG93bmVyX2lkID0gMSkpPGJyPg0KwqDCoMKgwqDC oMKgwqDCoCBSb3dzIFJlbW92ZWQgYnkgRmlsdGVyOiAxPGJyPg0KwqDCoCAtJmd0O8KgIEluZGV4 IFNjYW4gdXNpbmcgZm9sZGVyX3BrZXkgb24gZm9sZGVyIGbCoCAoY29zdD0wLjE1Li4zLjE3IHJv d3M9MSB3aWR0aD0zNikgKGFjdHVhbCB0aW1lPTAuMDA1Li4wLjAwNiByb3dzPTEgbG9vcHM9Myk8 YnI+DQrCoMKgwqDCoMKgwqDCoMKgIEluZGV4IENvbmQ6IChkb2MuZm9sZGVyX2lkID0gaWQpPGJy Pg0KwqBQbGFubmluZyB0aW1lOiAwLjI2NyBtczxicj4NCsKgRXhlY3V0aW9uIHRpbWU6IDAuMDk0 IG1zPGJyPg0KKDggcm93cyk8L2Rpdj4NCjwvZGl2Pg0KDQo8ZGl2PsKgPC9kaXY+DQoNCjxkaXY+ wqA8L2Rpdj4NCg0KPGRpdj5JcyB0aGUgYSB3YXkgdG8gd3JpdGUgYSBxdWVyeSB3aGljaCB1c2Vz IGFuIGluZGV4IGVmZmljaWVudGx5IGZvciBzdWNoIGEgc2NoZW1hPzwvZGl2Pg0KDQo8ZGl2PsKg PC9kaXY+DQoNCjxkaXY+SSYjMzk7ZCBsaWtlIHRvIGVsaW1pbmF0ZSB0aGUgRmlsdGVyOiAoKGZv bGRlcl9pZCBJUyBOT1QgTlVMTCkgT1IgKG93bmVyX2lkID0gMSkpIGFuZCByYXRoZXIgaGF2ZSAm cXVvdDtpbmRleCBjb25kJnF1b3Q7IGluc3RlZCwgaXMgdGhhdCBwb3NzaWJsZT88L2Rpdj48L2Js b2NrcXVvdGU+PGRpdj48YnI+PC9kaXY+PGRpdj55b3VyIGV4YW1wbGUgaXMgcGFydGlhbGx5IGJy b2tlbiAtIEFOQUxZWkUgYW5kIGhhc2hqb2luIGFuZCBzZXFzY2FuIHBlbmFsaXphdGlvbiBhcmUg bWlzc2luZyAtIGluZGV4IHNjYW4gaXMgbm90IHVzZWQgZHVlIHRvbyBzbWFsbCB0YWJsZSBzaXpl czxicj4NCg0KPGJyPjwvZGl2PjxkaXY+SSB0ZXN0ZWQgOS41LCBwcm9iYWJseSBzYW1lIGFzIDku NCBhbmQgdGhlcmUgaW5kZXhlcyBhcmUgdXNlZDxicj48YnI+cG9zdGdyZXM9IyBzZXQgZW5hYmxl X2hhc2hqb2luIHRvIG9mZjs8YnI+U0VUPGJyPlRpbWU6IDAuNDczIG1zPGJyPnBvc3RncmVzPSMg c2V0IGVuYWJsZV9zZXFzY2FuIHRvIG9mZjs8YnI+U0VUPGJyPlRpbWU6IDAuOTA0IG1zPGJyPnBv c3RncmVzPSMgZXhwbGFpbiBzZWxlY3QgPGEgaHJlZj0iaHR0cDovL2YuaWQiPmYuaWQ8L2E+LCA8 YSBocmVmPSJodHRwOi8vZi5uYW1lIj5mLm5hbWU8L2E+LCA8YSBocmVmPSJodHRwOi8vZG9jLmlk Ij5kb2MuaWQ8L2E+LCBkb2Mub3duZXJfaWQsIDxhIGhyZWY9Imh0dHA6Ly9kb2MubmFtZSI+ZG9j Lm5hbWU8L2E+PGJyPg0KDQpGUk9NIGRvY3VtZW50IGRvYyBsZWZ0IG91dGVyIGpvaW4gZm9sZGVy IGYgT04gZG9jLmZvbGRlcl9pZCA9IDxhIGhyZWY9Imh0dHA6Ly9mLmlkIj5mLmlkPC9hPjxicj5X SEVSRSBkb2MuZm9sZGVyX2lkIGlzIG5vdCBudWxsIE9SIGRvYy5vd25lcl9pZCA9IDE7PGJyPsKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBRVUVSWSBQTEFOwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIDxicj4NCg0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSAPGJyPsKgTWVyZ2UgTGVmdCBKb2luwqAgKGNvc3Q9MC4yNi4uMjQu Mzggcm93cz0zIHdpZHRoPTMyKTxicj7CoMKgIE1lcmdlIENvbmQ6IChkb2MuZm9sZGVyX2lkID0g PGEgaHJlZj0iaHR0cDovL2YuaWQiPmYuaWQ8L2E+KTxicj4NCg0KwqDCoCAtJmd0O8KgIEluZGV4 IFNjYW4gdXNpbmcgZG9jdW1lbnRfZm9sZGVyX2lkeCBvbiBkb2N1bWVudCBkb2PCoCAoY29zdD0w LjEzLi4xMi4yMCByb3dzPTMgd2lkdGg9MjMpPGJyPsKgwqDCoMKgwqDCoMKgwqAgRmlsdGVyOiAo KGZvbGRlcl9pZCBJUyBOT1QgTlVMTCkgT1IgKG93bmVyX2lkID0gMSkpPGJyPsKgwqAgLSZndDvC oCBJbmRleCBTY2FuIHVzaW5nIGZvbGRlcl9wa2V5IG9uIGZvbGRlciBmwqAgKGNvc3Q9MC4xMy4u MTIuMTYgcm93cz0yIHdpZHRoPTEzKTxicj4NCg0KwqBQbGFubmluZyB0aW1lOiAwLjY2MyBtczxi cj4oNiByb3dzKTxicj48YnI+PC9kaXY+PGRpdj5kZWZhdWx0IDkuMiwgOS4zLCAuLi48YnI+PGJy PnBvc3RncmVzPSMgZXhwbGFpbiBzZWxlY3QgPGEgaHJlZj0iaHR0cDovL2YuaWQiPmYuaWQ8L2E+ LCA8YSBocmVmPSJodHRwOi8vZi5uYW1lIj5mLm5hbWU8L2E+LCA8YSBocmVmPSJodHRwOi8vZG9j LmlkIj5kb2MuaWQ8L2E+LCBkb2Mub3duZXJfaWQsIDxhIGhyZWY9Imh0dHA6Ly9kb2MubmFtZSI+ ZG9jLm5hbWU8L2E+PGJyPg0KDQpGUk9NIGRvY3VtZW50IGRvYyBsZWZ0IG91dGVyIGpvaW4gZm9s ZGVyIGYgT04gZG9jLmZvbGRlcl9pZCA9IDxhIGhyZWY9Imh0dHA6Ly9mLmlkIj5mLmlkPC9hPjxi cj5XSEVSRSBkb2MuZm9sZGVyX2lkIGlzIG5vdCBudWxsIE9SIGRvYy5vd25lcl9pZCA9IDE7PGJy PsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IFFVRVJZIFBMQU7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIDxicj4NCg0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA PGJyPsKgSGFzaCBMZWZ0IEpvaW7CoCAoY29zdD0xLjA0Li4yLjEyIHJvd3M9MyB3aWR0aD0zMik8 YnI+wqDCoCBIYXNoIENvbmQ6IChkb2MuZm9sZGVyX2lkID0gPGEgaHJlZj0iaHR0cDovL2YuaWQi PmYuaWQ8L2E+KTxicj7CoMKgIC0mZ3Q7wqAgU2VxIFNjYW4gb24gZG9jdW1lbnQgZG9jwqAgKGNv c3Q9MC4wMC4uMS4wNSByb3dzPTMgd2lkdGg9MjMpPGJyPg0KDQrCoMKgwqDCoMKgwqDCoMKgIEZp bHRlcjogKChmb2xkZXJfaWQgSVMgTk9UIE5VTEwpIE9SIChvd25lcl9pZCA9IDEpKTxicj7CoMKg IC0mZ3Q7wqAgSGFzaMKgIChjb3N0PTEuMDIuLjEuMDIgcm93cz0yIHdpZHRoPTEzKTxicj7CoMKg wqDCoMKgwqDCoMKgIC0mZ3Q7wqAgU2VxIFNjYW4gb24gZm9sZGVyIGbCoCAoY29zdD0wLjAwLi4x LjAyIHJvd3M9MiB3aWR0aD0xMyk8YnI+KDYgcm93cyk8YnI+PGJyPjwvZGl2PjxkaXY+YW5kIDku MiBhZnRlciBoYXNoam9pbiBhbmQgaW5kZXhzY2FuIHBlbmFsaXphdGlvbjxicj4NCg0KPGJyPnBv c3RncmVzPSMgZXhwbGFpbiBzZWxlY3QgPGEgaHJlZj0iaHR0cDovL2YuaWQiPmYuaWQ8L2E+LCA8 YSBocmVmPSJodHRwOi8vZi5uYW1lIj5mLm5hbWU8L2E+LCA8YSBocmVmPSJodHRwOi8vZG9jLmlk Ij5kb2MuaWQ8L2E+LCBkb2Mub3duZXJfaWQsIDxhIGhyZWY9Imh0dHA6Ly9kb2MubmFtZSI+ZG9j Lm5hbWU8L2E+PGJyPkZST00gZG9jdW1lbnQgZG9jIGxlZnQgb3V0ZXIgam9pbiBmb2xkZXIgZiBP TiBkb2MuZm9sZGVyX2lkID0gPGEgaHJlZj0iaHR0cDovL2YuaWQiPmYuaWQ8L2E+PGJyPg0KDQpX SEVSRSBkb2MuZm9sZGVyX2lkIGlzIG5vdCBudWxsIE9SIGRvYy5vd25lcl9pZCA9IDE7PGJyPsKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBRVUVSWSBQTEFOwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIDxicj7ilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIA8YnI+DQoNCsKgTWVyZ2UgTGVmdCBKb2luwqAgKGNvc3Q9MC4wMC4uMjQu NjIgcm93cz0zIHdpZHRoPTMyKTxicj7CoMKgIE1lcmdlIENvbmQ6IChkb2MuZm9sZGVyX2lkID0g PGEgaHJlZj0iaHR0cDovL2YuaWQiPmYuaWQ8L2E+KTxicj7CoMKgIC0mZ3Q7wqAgSW5kZXggU2Nh biB1c2luZyBkb2N1bWVudF9mb2xkZXJfaWR4IG9uIGRvY3VtZW50IGRvY8KgIChjb3N0PTAuMDAu LjEyLjMyIHJvd3M9MyB3aWR0aD0yMyk8YnI+DQoNCsKgwqDCoMKgwqDCoMKgwqAgRmlsdGVyOiAo KGZvbGRlcl9pZCBJUyBOT1QgTlVMTCkgT1IgKG93bmVyX2lkID0gMSkpPGJyPsKgwqAgLSZndDvC oCBJbmRleCBTY2FuIHVzaW5nIGZvbGRlcl9wa2V5IG9uIGZvbGRlciBmwqAgKGNvc3Q9MC4wMC4u MTIuMjggcm93cz0yIHdpZHRoPTEzKTxicj4oNSByb3dzKTxicj48YnI+VGltZTogMi4yNTggbXM8 YnI+PGJyPjwvZGl2PjxkaXY+V2hhdCBpcyB5b3VyIFBvc3RncmVTUUw/PGJyPg0KDQo8YnI+PC9k aXY+PGRpdj5SZWdhcmRzPGJyPjxicj48L2Rpdj48ZGl2PlBhdmVsPGJyPjxicj48L2Rpdj48ZGl2 PlAuUy4gdGVuIHllYXJzIGFnbyBJIGhhZCBhIHNpbWlsYXIgaXNzdWUgLSAmcXVvdDtPUiZxdW90 OyBwcmVkaWthdGVzIGNhbiBiZSByZXBsYWNlZCBieSBVTklPTjxicj48YnI+PC9kaXY+PGRpdj55 b3UgY2FuIHRyeTo8YnI+PGJyPjwvZGl2PjxkaXY+U0VMRUNUICogRlJPTTxicj4NCg0KPC9kaXY+ PGRpdj4oU0VMRUNUICogRlJPTSBkb2MgPGJyPsKgIFdIRVJFIGZvbGRlcl9pZCBJUyBOT1QgTlVM TDxicj48L2Rpdj48ZGl2PlVOSU9OPGJyPjwvZGl2PjxkaXY+wqAgU0VMRUNUICogRlJPTSBkb2M8 YnI+PC9kaXY+PGRpdj7CoCBXSEVSRSBvd25lcl9pZCA9IDEpIHM8YnI+PC9kaXY+PGRpdj7CoCBM RUZUIEpPSU4gZm9sZGVyIE9OIHMuZm9sZGVyX2lkID0gPGEgaHJlZj0iaHR0cDovL2ZvbGRlci5p ZCI+Zm9sZGVyLmlkPC9hPjxicj4NCg0KPGJyPjwvZGl2PjxkaXY+b3Igc29tZSBzaW1pbGFyIG1h Z2ljPGJyPjwvZGl2PjxkaXY+PGJyPjxkaXY+c2VsZWN0IDxhIGhyZWY9Imh0dHA6Ly9mLmlkIiB0 YXJnZXQ9Il9ibGFuayI+Zi5pZDwvYT4sIDxhIGhyZWY9Imh0dHA6Ly9mLm5hbWUiIHRhcmdldD0i X2JsYW5rIj5mLm5hbWU8L2E+LCA8YSBocmVmPSJodHRwOi8vZG9jLmlkIiB0YXJnZXQ9Il9ibGFu ayI+ZG9jLmlkPC9hPiwgZG9jLm93bmVyX2lkLCA8YSBocmVmPSJodHRwOi8vZG9jLm5hbWUiIHRh cmdldD0iX2JsYW5rIj5kb2MubmFtZTwvYT48L2Rpdj4NCg0KDQoNCjxkaXY+RlJPTSBkb2N1bWVu dCBkb2MgbGVmdCBvdXRlciBqb2luIGZvbGRlciBmIE9OIGRvYy5mb2xkZXJfaWQgPSA8YSBocmVm PSJodHRwOi8vZi5pZCIgdGFyZ2V0PSJfYmxhbmsiPmYuaWQ8L2E+PC9kaXY+DQoNCjxkaXY+V0hF UkUgZG9jLmZvbGRlcl9pZCBpcyBub3QgbnVsbCBPUiBkb2Mub3duZXJfaWQgPSAxOzwvZGl2Pjxi cj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PsKgPC9kaXY+PGJsb2NrcXVvdGUgY2xhc3M9Imdt YWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2luOjBweCAwcHggMHB4IDAuOGV4O2JvcmRlci1sZWZ0OjFw eCBzb2xpZCByZ2IoMjA0LDIwNCwyMDQpO3BhZGRpbmctbGVmdDoxZXgiPg0KDQoNCg0KPGRpdj7C oDwvZGl2Pg0KDQo8ZGl2Pg0KPGRpdj4tLQ0KPGRpdj48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6 YXJpYWwsaGVsdmV0aWNhLHNhbnMtc2VyaWYiPjxiPkFuZHJlYXMgSm9zZXBoIEtyb2doPC9iPjwv c3Bhbj48L2Rpdj4NCg0KPGRpdj48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6YXJpYWwsaGVsdmV0 aWNhLHNhbnMtc2VyaWYiPkNUTyAvIFBhcnRuZXI8L3NwYW4+IC0gVmlzZW5hIEFTPC9kaXY+DQoN CjxkaXY+PHNwYW4gc3R5bGU9ImZvbnQtZmFtaWx5OmFyaWFsLGhlbHZldGljYSxzYW5zLXNlcmlm Ij5Nb2JpbGU6IDxhIGhyZWY9InRlbDolMkI0NyUyMDkwOSUyMDU2JTIwOTYzIiB2YWx1ZT0iKzQ3 OTA5NTY5NjMiIHRhcmdldD0iX2JsYW5rIj4rNDcgOTA5IDU2IDk2MzwvYT48L3NwYW4+PC9kaXY+ DQoNCjxkaXY+PGEgaHJlZj0ibWFpbHRvOmFuZHJlYXNAdmlzZW5hLmNvbSIgdGFyZ2V0PSJfYmxh bmsiPmFuZHJlYXNAdmlzZW5hLmNvbTwvYT48L2Rpdj4NCg0KPGRpdj48YSBocmVmPSJodHRwczov L3d3dy52aXNlbmEuY29tIiB0YXJnZXQ9Il9ibGFuayI+d3d3LnZpc2VuYS5jb208L2E+PC9kaXY+ DQoNCjxkaXYgc3R5bGU9InBhZGRpbmctdG9wOjVweCI+PGEgaHJlZj0iaHR0cHM6Ly93d3cudmlz ZW5hLmNvbSIgdGFyZ2V0PSJfYmxhbmsiPjxpbWcgYWx0PSIiIHNyYz0iY2lkOnBhcnRfRjkyNjIw Nzg0MzUxN0pXWlA0NSI+PC9hPjwvZGl2Pg0KPC9kaXY+DQo8L2Rpdj48L2Jsb2NrcXVvdGU+PC9k aXY+PGJyPjwvZGl2PjwvZGl2Pg0K --001a11c34f7edc99da05005fa818-- --001a11c34f7edc99de05005fa819 Content-Type: image/png Content-Disposition: inline Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: 1144373191533b6b_0.1 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 --001a11c34f7edc99de05005fa819--