Received: from malur.postgresql.org ([2a02:16a8:dc51::56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1ffRQ6-0005e5-K5 for pgsql-performance@arkaria.postgresql.org; Tue, 17 Jul 2018 14:57:42 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1ffRQ4-00029g-9q for pgsql-performance@arkaria.postgresql.org; Tue, 17 Jul 2018 14:57:40 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1ffRQ3-00029Z-PG for pgsql-performance@lists.postgresql.org; Tue, 17 Jul 2018 14:57:39 +0000 Received: from mail-wr1-x442.google.com ([2a00:1450:4864:20::442]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1ffRQ0-0000UH-J9 for pgsql-performance@lists.postgresql.org; Tue, 17 Jul 2018 14:57:38 +0000 Received: by mail-wr1-x442.google.com with SMTP id s11-v6so1560501wra.13 for ; Tue, 17 Jul 2018 07:57:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=hfcx0ds8zZYlB9wG1BDxL76Zh1vfch2TSnSUMU/gsF0=; b=QaFKmPiUo5hl1bYFkMyz1gsJE707g8kt6A5Y6STVcZ93ADp6BwcCPhkRVy3oKpNmKH vNxAxUPd8MZHGaJBrGOvjhpshQCnggVmxAuuwCsT9UKXpwMs1QxphgStIMjihUuH7KXK kPlJ0SxydEr9jyv/thnCX9EqzAmTnnTIaoVytta0INkIfPYQDHMX0nZIHbOJxeKEU/gM y7qRQa3QH13Tw1NL3lnx3bWGwsU7b6a7fMPLCsjz6Ce0gcIIQcbr1non/Bjz5RMiGyCC jVtnf8NxSNb5pNIIGWJLua7wsZJT5O0WkdTR2ZpnGVaG9aEeXDAVQEAERYs+wN0QPmcx tDGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=hfcx0ds8zZYlB9wG1BDxL76Zh1vfch2TSnSUMU/gsF0=; b=Hxp+wUX4YtjgTBIjw6Hy7Ztvj+nLS6xsvSCmkGZgaBU8rV8rbNCyXL1iiN6BRBmVHN IOmK4Bv3LgfThuXkMKJ3WzP9jszwbWIVE7raLW6Owq4wYz7Cbl1mTfnHhSBKBDY/hyYC 28Kw0pnRLRlQIenZqTWYzLeg7y0QkEovf6vNJPzvReHvQMt56+m9xvxyrq3h6twmL+EW B+nuRBOoHteOaT3Frp4S1cIY0G2Za9U3gYV1DW/DZyDCmojV8pwMv/rzy6zLuD2OzqZL iXgMadx3igdUenAcwP5AONv1bFEp8IslhugEjLoLCCN8VgsPSfHOqIPG59gDi2cH8s7E dxRQ== X-Gm-Message-State: AOUpUlFxB8nd5cGCXEIzom7SW+ZZ3q5nxe8ppEZ7VzSVqXfPduIKWoE0 c+KTWKX9vJq81vwVwtlObr7CJj9XCIEwjjjiDvKi+INJ7+ePMDVPX2fyoc24sZVhkTOIjz+vNAz OUlMKp29M96RBjvHFzxFNO/mv55dmWZF2UAujCUTnNLgwruHyPcBuufAzo7/u9MVXuDmlK8ybzm LZhjVuw2z9dJe/gTCY55+QJg== X-Google-Smtp-Source: AAOMgpfIBhLkGoleaTtj1qff7IS9uRCekxBf/qD/ixsy3I+/XTbDBvhjiCrxF+QgGKGCvBlPpABFPw== X-Received: by 2002:adf:93c3:: with SMTP id 61-v6mr1599970wrp.18.1531839454182; Tue, 17 Jul 2018 07:57:34 -0700 (PDT) Received: from [10.137.2.21] (static-84-42-175-93.net.upcbroadband.cz. [84.42.175.93]) by smtp.gmail.com with ESMTPSA id u18-v6sm1692412wrm.80.2018.07.17.07.57.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 17 Jul 2018 07:57:32 -0700 (PDT) Subject: Re: Special bloom index of INT, BIGINT, BIT, VARBIT for bitwise operation To: Takao Magoori , pgsql-performance@lists.postgresql.org References: From: Tomas Vondra Message-ID: Date: Tue, 17 Jul 2018 16:57:32 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 07/11/2018 08:02 AM, Takao Magoori wrote: > Hello, > > I have a table which has billions of rows and I want to select it by > bitwise operation like, > > =# CREATE TABLE IF NOT EXISTS t_bitwise ( > id INTEGER NOT NULL > ,status_bigint BITINT NOT NULL > ,status_bit BIT(32) NOT NULL > ); > > =# INSERT INTO t_bitwise (id, status_bigint, status_bit) SELECT > id > ,(random() * 4294967295)::BIGINT > ,(random() * 4294967295)::BIGINT::BIT(32) > FROM generate_series(1, 3000000000) as t(id); > > =# SELECT * FROM t_bitwise WHERE > status_bigint & 170 = 170 > OR status_bigint & 256 = 256; > > =# SELECT * FROM t_bitwise WHERE > status_bit & b'00000000000000000000000010101010'::BIT(32) = > b'00000000000000000000000010101010'::BIT(32) > OR status_bit & b'00000000000000000000000100000000'::BIT(32) = > b'00000000000000000000000100000000'::BIT(32); > > Yes, these SELECT statements scan all rows. I guess possible index types are > > - Expression indexes ? > - Partial Indexes ? > - GIN ? > - GIST ? > - bloom index ? > > I googled but I feel there is no good solution and it would be good if > I hava "bloom index specific for bitwise operation". > > In case of normal bloom index, a value is hashed into a few bits which > is mapped to a signature (default 80 bits). > This is a lossy representation of the original value, and as such is > prone to reporting false positives which requires "Recheck" process at > SELECT. The more rows or the more complex condition, the more > execution time. > > My idea is that, in case of index for bitwise operation, each bit > should be mapped to exactly same bit on a signature (One to one > mapping). No false positives. No "Recheck" process is required. If the > target coulmn is BIT(32), just 32 bits signature lengh is enough. > So you're not computing a hash at all, so calling this "bloom index" is rather misleading. Another question is where do you expect the performance advantage to come from? If the table is as narrow as this, such index will have almost the same size, and it won't allow fast lookups. > Is there any index module like this ? Since I am not familiar with C > and Postgresql, I can not write my own module. > I doubt there's a suitable index available currently. Perhaps a simple btree index could help, assuming it's (a) smaller than the table, (b) we can use IOS and (c) only a small fraction of the table matches. Another idea is to use partial indexes - one for each bit, i.e. CREATE INDEX ON t_bitwise (id) WHERE status_bit & b'10000000'::BIT(32) = b'10000000'::BIT(32); And then build the query accordingly. I wonder if it might work with BRIN indexes of some kind. If the range summary is defined as OR of the values, that might help, depending on variability within the page range. But that would probably require some development. regards -- Tomas Vondra http://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services