We are tracking manufactured components with an alphanumeric serial
number, which gives us a natural key. Naturally we set type affinity
TEXT on the key column. There are many tables linked through foreign key
relationships on this serial number.
On one table, the type affinity of the serial number FOREIGN KEY column
was incorrectly declared as INTEGER. Due to the flexibility of the type
affinity system, this never showed up as an issue. We were able to
INSERT valid TEXT values into the column with no problem. Everything
seemed to be working fine.
As the database grew modestly, some queries became very slow. After
making sure that all relevant columns were already automatically indexed
due to FOREIGN KEY and PRIMARY KEY declarations, I found the culprit.
After changing the type affinity on the bad table from INTEGER to TEXT,
the slow query which joined on that table sped up by two orders of
magnitude.
I'm happy enough with the end result, but I'd quite like to know why
this happened? Was SQLite building a different type of index under the
hood due to the declared type affinity? Did the difference in type
affinity of the compared columns prevent the query from using the index?
Was there some unnecessary type conversion going on which slowed things
down?
Here is an cut down example:
CREATE TABLE IF NOT EXISTS pcb_units (
serial_no TEXT NOT NULL,
PRIMARY KEY (serial_no),
-- Constraints enforcing serial number validity.
CONSTRAINT family_check
CHECK (SUBSTR(serial_no, 6, 1) BETWEEN 'A' AND 'Z' OR
SUBSTR(serial_no, 6, 1) BETWEEN '0' AND '9'),
CONSTRAINT model_check
CHECK (SUBSTR(serial_no, 7, 1) BETWEEN 'A' AND 'Z' OR
SUBSTR(serial_no, 7, 1) BETWEEN '0' AND '9'),
CONSTRAINT reserved_check
CHECK (SUBSTR(serial_no, 8, 1) == '0'),
CONSTRAINT unit_number_check
CHECK (CAST(SUBSTR(serial_no, 9, 4) AS INTEGER) BETWEEN 0 AND 9999)
);
CREATE TABLE assembly_pcb_units (
pcb_serial_no INTEGER NOT NULL, -- This is the bad column
assembly_serial_no TEXT NOT NULL,
added_time TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
added_by TEXT NOT NULL,
CONSTRAINT pcb_in_one_assembly_only
UNIQUE(pcb_serial_no),
FOREIGN KEY (assembly_serial_no)
REFERENCES assembly_units(assembly_serial_no),
FOREIGN KEY (pcb_serial_no)
REFERENCES pcb_units(serial_no),
FOREIGN KEY (added_by)
REFERENCES sti_users(user_id)
);
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users