8.7. ²¿·ÖË÷Òý

²¿·ÖË÷Òý£¨partial index£© Êǽ¨Á¢ÔÚÒ»¸ö±íµÄ×Ó¼¯ÉϵÄË÷Òý£»¸Ã×Ó¼¯ÊÇÓÉÒ»¸öÌõ¼þ±í´ïʽ¶¨ÒåµÄ (½Ð×ö²¿·ÖË÷ÒýµÄν´Ê)£® ¸ÃË÷ÒýÖ»°üº¬±íÖÐÄÇЩÂú×ãÕâ¸öν´ÊµÄÐУ®

²¿·ÖË÷ÒýµÄÖ÷Òª¶¯»úÊÇΪÁ˱ÜÃâ¶ÔÆÕͨÊýÖµ½¨Á¢Ë÷Òý£ ÒòΪÈç¹ûÒ»¸öÔÚÒ»¸öÆÕͨÊýÖµ(ÄÇÖÖÖ»Õ¼±íÖÐËùÓÐÐм¸¸ö°Ù·ÖµãµÄÊýÖµ) ÉϵIJéѯ²»»áʹÓÃË÷Òý£¬ ÄÇô¾ÍûÓÐÔÚË÷ÒýÖб£´æÕâЩ(ÆÕͨ)ÐеıØÒª£® ÕâÑù¾Í¿ÉÒÔ¼õСË÷ÒýµÄ³ß´ç£¬ÕâÑù¾Í¿ÉÒÔÌá¸ßÄÇЩÕæÕýʹÓÃË÷ÒýµÄ²éѯµÄËٶȣ® ͬʱËüÒ²ÄÜÌá¸ßÐí¶à±í¸üвÙ×÷µÄËٶȣ¬ÒòΪ²»ÊÇËùÓÐÇé¿ö¶¼ÐèÒª¸üÐÂË÷Òý£® Example 8-1 ÏÔʾÁËÒ»¸öDZÔÚµÄÕâ·½ÃæÓ¦ÓõÄÀý×Ó£®

Example 8-1. ÉèÖÃÒ»¸ö²¿·ÖË÷ÒýÒÔÅųýÆÕͨÊýÖµ

¼ÙÉèÄãÔÚÒ»¸öÊý¾Ý¿âÖд洢 web ·þÎñÆ÷µÄ·ÃÎÊÈÕÖ¾£® ´ó¶àÊý·ÃÎÊÊÇ´ÓÄãµÄ×éÖ¯ÄÚ²¿µÄ IP ·¶Î§·¢ÆðµÄ£¬µ«Ò²ÓÐһС²¿·Ö À´×ÔÆäËüµØ·½(±ÈÈçÄÇЩͨ¹ý²¦ºÅ½øÐÐÁª½ÓµÄ¹ÍÔ±)£® Èç¹ûÄãËÑË÷µÄÖ÷ÒªÊÇÀ´×ÔÍⲿ·ÃÎ浀 IP£¬ÄÇôÄã¿ÉÄܾͲ»ÐèÒª¶ÔÄÇЩ ¶ÔÓ¦ÄãµÄ×éÖ¯µÄ×ÓÍøµÄ IP ·¶Î§½øÐÐË÷Òý£®

¼ÙÉè±íÏóÏÂÃæÕâÑù¡Ã

CREATE TABLE access_log (
    url varchar,
    client_ip inet,
    ...
);

Òª´´½¨·ûºÏÎÒÃǵÄÀý×ÓµÄË÷Òý£¬Ê¹ÓÃÏóÏÂÃæÕâÑùµÄÃüÁî¡Ã

CREATE INDEX access_log_client_ip_ix ON access_log (client_ip)
    WHERE NOT (client_ip > inet '192.168.100.0' AND client_ip < inet '192.168.100.255');

Ò»¸ö¿ÉÒÔʹÓÃÕâ¸öË÷ÒýµÄµäÐ͵IJéѯÏóÕâÑù¡Ã

SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '212.78.10.32';

Ò»¸ö²»ÄÜʹÓÃÕâ¸öË÷ÒýµÄ²éѯ¿ÉÒÔÊÇ¡Ã

SELECT * FROM access_log WHERE client_ip = inet '192.168.100.23';

ÎÒÃÇͨ¹ý¹Û²ì¿ÉÒÔ¿´³ö£¬ÕâÖÖÀàÐ͵IJ¿·ÖË÷ÒýÒªÇóÆÕͨÊýÖµÊÇ¿ÉÒÔ Ô¤¼ÆµÄ£®Èç¹ûÊýÖµµÄ·Ö²¼ÊǹÌÓеÄ(À´×ÔÓ¦ÓÃ×ÔÉíµÄÐÔÖÊ)²¢ÇÒ ÊǾ²Ì¬µÄ(²»Ëæʱ¼ä¶ø¸Ä±ä)£¬ÄÇ×öµ½ÕâÒ»µã(¸ú×ÙÆÕͨÊýÖµ)²¢²»À§ÄÑ£¬µ«ÊÇ Èç¹ûÆÕͨÊýÖµÖ»ÊÇÒòΪһÖµÄÊý¾Ý×°ÔØ£¬ÄÇôËü¿ÉÄܾÍÒª»¨ºÜ¶àά»¤ÐÔ¹¤×÷£®

ÁíÍâÒ»¸ö¿ÉÄÜÊÇ°ÑÄÇЩµäÐ͵IJéѯ¹¤×÷²»¸ÐÐËȤµÄÊýÖµÅųýÔÚ Ë÷ÒýÖ®Í⣻Õâ¸ö¿ÉÄÜÔÚ Example 8-2 ÀïÏÔʾ£® Õâ¸ö½á¹ûÓÐÓëÉÏÃæÁгöµÄͬÑùµÄÓŵ㣬µ«ÊÇËüÍêÈ«¾Ü¾øÁËͨ¹ýË÷Òý ·ÃÎÊ"²»¸ÐÐËȤ"µÄÊýÖµ£¬¼´Ê¹Ë÷ÒýɨÃè¿ÉÄܶÔÄÇЩÊý¾Ý Ò²ÓÐÀû£®ÏÔÈ»£¬ÎªÕâÖÖÇé¿öÉèÖò¿·ÖË÷ÒýÐèÒª·Ç³£×ÐϸÒÔ¼°ÐèÒª´óÁ¿ÊÔÑ飮

Example 8-2. ÉèÖÃÒ»¸ö²¿·ÖË÷ÒýÒÔÅųý²»¸ÐÐËȤµÄÊýÖµ

Èç¹ûÄãÓÐÒ»¸ö±í£¬°üº¬ÒѸ¶¿îºÍδ¸¶¿îµÄ¶¨µ¥£¬¶øδ¸¶¿îµÄ¶¨µ¥ Ö»Õ¾×ܱíµÄһС²¿·Ö²¢ÇÒËüÊǾ­³£Ê¹ÓõIJ¿·Ö£¬ÄÇôÄã¿ÉÒÔͨ¹ý Ö»ÔÚδ¸¶¿î¶¨µ¥ÉÏ´´½¨Ò»¸öË÷ÒýÀ´¸ÄÉÆÐÔÄÜ£®´´½¨Ë÷ÒýµÄÃüÁî¿´ÆðÀ´»áÏóÕâÑù¡Ã

CREATE INDEX orders_unbilled_index ON orders (order_nr)
    WHERE billed is not true;

¿ÉÄÜÓõ½Õâ¸öË÷ÒýµÄ²éѯ¿´ÆðÀ´Ïó

SELECT * FROM orders WHERE billed is not true AND order_nr < 10000;

²»¹ý£¬¸ÃË÷ÒýÒ²¿ÉÒÔÓÃÓÚÄÇЩÍêÈ«²»Éæ¼° order_nr µÄ²éѯ£¬±ÈÈ磬

SELECT * FROM orders WHERE billed is not true AND amount > 5000.00;

Õâ¸ö²éѯ²»ÏóÔÚ amount ×Ö¶ÎÉϵIJ¿·ÖË÷ÒýÄÇôÓÐЧ£¬ ÒòΪϵͳ±ØÐëɨÃèÕû¸öË÷Òý£®µ«ÊÇ£¬Èç¹ûδ¸¶¿îµÄ¶¨µ¥Ïà¶Ô½ÏÉÙ£¬ ÄÇôÓÃÕâ¸ö²¿·ÖË÷ÒýÕÒ³öδ¸¶¿îµÄ¶¨µ¥½«»á¸ü¿ìЩ£®

Çë×¢ÒâÏÂÃæÕâ¸ö²éѯÎÞ·¨Ê¹ÓÃÕâ¸öË÷Òý¡Ã

SELECT * FROM orders WHERE order_nr = 3501;

¶¨µ¥ 3501 ¿ÉÄÜÊÇÒѸ¶¿îÒ²¿ÉÄÜÊÇδ¸¶¿î£®

Example 8-2 »¹ËµÃ÷Á˽¨ÁËË÷ÒýµÄ×ֶΠºÍÔÚν´ÊÖÐʹÓõÄ×ֶβ»±ØÏàÅ䣮PostgreSQL Ö§³Ö´øÈÎÒâν´ÊµÄ²¿·ÖË÷Òý£¬Ö»ÒªÊÇÖ»Éæ¼°±»Ë÷Òý±íµÄ×ֶξÍÐУ® ²»¹ý£¬ÎÒÃÇÒª¼ÇסµÄÊÇν´Ê±ØÐëºÍÄÇЩϣÍû ´Ó¸ÃË÷ÒýÖлñÒæµÄ²éѯÖеÄÌõ¼þÏàÆ¥Å䣮׼ȷ˵£¬Ö»ÓÐÔÚϵͳ Äܹ»Ê¶±ð³ö¸Ã²éѯµÄ WHERE Ìõ¼þÔÚÊýѧÉÏÔ̺­ Á˸ÃË÷ÒýµÄν´Êʱ£¬Õâ¸ö²¿·ÖË÷Òý²ÅÄÜÓÃÓڸòéѯ£® PostgreSQL »¹Ã»Óи´ÔÓµÄÀíÂÛУ¶¨ÓÃÓÚ Ê¶±ðÄÇЩÐÎʽ²»Í¬µ«ÊýѧÉÏÏàµÈµÄν´Ê£®(×öÕâÑùµÄÀíÂÛУ¶¨²»½ö·Ç³£À§ÄÑ£¬ ¶øÇÒÔÚʵ¼ÊʹÓÃÖÐÒ²¿ÉÄܷdz£Âý£®) ϵͳ¿ÉÒÔʶ±ð¼òµ¥µÄ²»ÏàµÈÔ̺­£¬±ÈÈç "x < 1" Ô̺­ "x < 2"£»·ñÔò£¬Î½´ÊÌõ¼þ±ØÐë׼ȷƥÅä ²éѯµÄ WHERE Ìõ¼þ£¬Òª²»È»ÏµÍ³½«ÎÞ·¨Ê¶±ð¸ÃË÷ÒýÊÇ¿ÉÓõģ®

²¿·ÖË÷ÒýµÄµÚÈýÖÖ¿ÉÄÜÓÃ;ÍêÈ«²»ÒªÇóË÷ÒýÔÚ²éѯÖеõ½Ê¹Óã® ÕâÀïµÄ¸ÅÄîÊÇÔÚÒ»¸ö±íµÄÒ»¸ö×Ó¼¯Àï´´½¨Ò»¸öΨһË÷Òý£¬ Èç Example 8-3 ÀïÃèÊö£® ÕâÑù¾ÍÇ¿ÖÆÔÚÂú×ãν´ÊµÄÐÐÖеÄΨһÐÔ£¬¶ø²»ÓÃÔ¼ÊøÄÇЩ²»ÐèÒª ΨһµÄÐУ®

Example 8-3. ÉèÖÃÒ»¸ö²¿·ÖΨһË÷Òý

¼ÙÉèÎÒÃÇÓÐÒ»¸öÃèÊö²âÊÔÊä³öµÄ±í£®ÎÒÃÇÏ£ÍûÈ·±£ÔÚÒ»¶¨µÄ Ä¿±êºÍ¿ÎÌâµÄ×éºÏÖÐÖ»ÓÐÒ»¸ö"³É¹¦"¼Ç¼£¬ µ«ÊÇ¿ÉÒÔÓÐÈÎÒâÊýÁ¿µÄ"²»³É¹¦"¼Ç¼£®ÏÂÃæÊÇʵÏÖ·½·¨¡Ã

CREATE TABLE tests (subject text,
                    target text,
                    success bool,
                    ...);
CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
    WHERE success;

Èç¹ûÖ»ÓÐÉÙÊý³É¹¦¼Ç¼¶øÓкܶ಻³É¹¦¼Ç¼£¬ÄÇô ÕâÊÇÒ»Öַdz£ÓÐЧµÄʵÏÖ·½·¨£®

×îºó£¬²¿·ÖË÷ÒýÒ²¿ÉÒÔÓÃÓÚ¸²¸ÇϵͳѡÔñµÄ²éѯ¹æ»®£® ¿ÉÄÜ»á³öÏÖÕâÑùµÄÇé¿ö¡ÃÈç¹ûÊý¾Ý¼¯µÄ·Ö²¼ÊDZȽÏÌض¨µÄÐÎ×´£¬ ÄÇô»áµ¼ÖÂϵͳÔÚ²»¸ÃʹÓÃË÷ÒýµÄʱºòʹÓÃËü£®ÔÚÕâÖÖÇé¿öÏ£¬ ÎÒÃÇ¿ÉÒÔ°ÑË÷ÒýÉèÖÃΪÔÚÎ¥·´(¹æÂÉ)µÄ²éѯÖв»¿ÉÓã® ͨ³£ PostgreSQL ¶ÔË÷ÒýµÄʹÓÃÊÇ»á×öºÏÀíµÄÑ¡ÔñµÄ (±ÈÈ磬ËüÔÚ¼ìË÷ÆÕͨÊýÖµµÄʱºò±ÜÃâʹÓÃËü£¬Òò´ËÇ°ÃæµÄÀý×Óʵ¼ÊÉÏ Ö»ÊǽÚÔ¼ÁËË÷ÒýµÄ³ß´ç£¬Ëü²¢²»ÒªÇó±ÜÃâË÷ÒýµÄʹÓÃ)£¬¶øÈç¹û³öÏÖÁË ´íÎóµÄ¹æ»®Ñ¡ÔñÄÇôÇëÌá½»Ò»¸ö³ô³æ±¨¸æ£®

Çë¼Çסһ¼þÊ¡ÃÉèÖÃÒ»¸ö²¿·ÖË÷Òý±íʾÄãÖÁÉٺͲéѯ¹æ»®Æ÷ÖªµÀµÄÒ»Ñù¶à£¬ ÌرðÊÇÄãÖªµÀʲô³¡ºÏÀïË÷ÒýÊÇÓÐЧµÄ£®ÒªÐγÉÕâЩֻÊÇÒªÇó¸»Óо­Ñé ºÍÀí½â PostgreSQL ÀïµÄË÷ÒýÊÇÈçºÎÔË×öµÄ£® ÔÚ´ó¶àÊýÇé¿öÏ£¬²¿·ÖË÷Òý¶ÔÆÕͨË÷ÒýµÄÓÅÊƲ¢²»Ì«Ã÷ÏÔ£®

¸ü¶àÓйز¿·ÖË÷ÒýµÄÐÅÏ¢¿ÉÒÔÔÚ ²¿·ÖË÷ÒýµÄʵÀý£¬ Partial indexing in POSTGRES: research project£¬ºÍ Generalized Partial Indexes »ñµÃ£®