[Oracle][Postgresql][mysql] the following table fields of the three database products have null values or are null. Test whether the index creation is effective

Posted by engelsol on Wed, 23 Feb 2022 15:21:50 +0100

/******************* postgresql database test starts***********************/
 

--This test is based on pg database version 10.11

postgres=# select version();
                           version
-------------------------------------------------------------
 PostgreSQL 10.11, compiled by Visual C++ build 1800, 64-bit
(1 Row record)


--Create a test table

create table t_index_null(id varchar(50),name text);

--Manufacturing test data

insert into t_index_null(id,name)
select t.id,'test'||t.id::varchar
  from (select generate_series as id
          from generate_series(1,100000) ) as t;

--Add a piece of data with null id

insert into t_index_null(name) values ('zqw01');

--Add a piece of data whose id is null character

insert into t_index_null(id,name) values ('','zqw02');

--Create index on id column

create index idx_t_index_null_id on t_index_null(id);


--Check and lock the data with id=1 to see if the execution plan will follow the index and execution plan

explain analyze 
select id,name
  from t_index_null 
 where id = '1';

                                                            QUERY PLAN
-------------------------------------------------------------------------------------------
 Index Scan using idx_t_index_null_id on t_index_null  (cost=0.29..8.31 rows=1 width=14) (actual time=0.061..0.062 rows=1 loops=1)
   Index Cond: ((id)::text = '1'::text)
 Planning time: 0.289 ms
 Execution time: 0.086 ms
(4 Row record)

 
--Check and lock the data with id = '' (empty character) to see whether the execution plan will follow the index and the execution plan

explain analyze 
select id,name
  from t_index_null 
 where id = '';

                                                             QUERY PLAN
-------------------------------------------------------------------------------------------
 Index Scan using idx_t_index_null_id on t_index_null  (cost=0.29..8.31 rows=1 width=14) (actual time=0.050..0.052 rows=1 loops=1)
   Index Cond: ((id)::text = ''::text)
 Planning time: 0.114 ms
 Execution time: 0.078 ms
(4 Row record)


--Check and lock the data with id is null (null character) to see whether the execution plan will follow the index and the execution plan

explain analyze 
select id,name
  from t_index_null 
 where id is null;

                                                            QUERY PLAN
-------------------------------------------------------------------------------------------
 Index Scan using idx_t_index_null_id on t_index_null  (cost=0.29..10.97 rows=3 width=14) (actual time=0.105..0.106 rows=1 loops=1)
   Index Cond: (id IS NULL)
 Planning time: 0.115 ms
 Execution time: 0.133 ms
(4 Row record)

/*********************oracle library test***************************/
-

-This test is based on oracle database version 11.2

SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0    Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production


--Create a test table

create table scott.t_index_null(id varchar2(50),name varchar2(4000));

--Manufacturing test data

insert into scott.t_index_null(id,name)
select level,'test'||level
  from dual 
 connect by level <= 100000;


--Add a piece of data with null id

insert into scott.t_index_null(name) values ('zqw01');

--Add a piece of data whose id is null character

insert into scott.t_index_null(id,name) values ('','zqw02');

--Create index on id column

create index idx_t_index_null_id on scott.t_index_null(id);


--Check and lock the data with id=1 to see whether the execution plan will follow the index. The execution plan will follow the index

set auto off

explain plan for
select id,name
  from scott.t_index_null 
 where id = '1';
 
select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 42603800

---------------------------------------------------------------------------------------------------
| Id  | Operation            | Name          | Rows  | Bytes | Cost (%CPU)| Time      |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |              |    1 |  2029 |    2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T_INDEX_NULL      |    1 |  2029 |    2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN        | IDX_T_INDEX_NULL_ID |    1 |      |    1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("ID"='1')

Note
-----
   - dynamic sampling used for this statement (level=2)

 
--Check and lock the data with id = '' (empty character) to see whether the execution plan will go through the index. From the following execution plan, id = '' filtering does not go through the index scanning, but through the whole table scanning

explain plan for
select id,name
  from scott.t_index_null 
 where id = '';

select * from table(dbms_xplan.display);  


PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1102671017

-----------------------------------------------------------------------------------
| Id  | Operation       | Name      | Rows  | Bytes | Cost (%CPU)| Time      |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |          |    1 |  2029 |    0   (0)|      |
|*  1 |  FILTER        |          |      |      |           |      |
|   2 |   TABLE ACCESS FULL| T_INDEX_NULL |   118K|   229M|   104   (2)| 00:00:02 |
-----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(NULL IS NOT NULL)

Note
-----
   - dynamic sampling used for this statement (level=2)

                                     
--Check and lock the data with id is null (null character) to see whether the execution plan will go through the index. From the following execution plan, id is null also does not go through the index scanning, but goes through the whole table scanning

explain plan for
select id,name
  from scott.t_index_null 
 where id is null;
                                                            
select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1935092368

----------------------------------------------------------------------------------
| Id  | Operation      | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |         |     4 |  8116 |   104   (2)| 00:00:02 |
|*  1 |  TABLE ACCESS FULL| T_INDEX_NULL |     4 |  8116 |   104   (2)| 00:00:02 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("ID" IS NULL)

Note
-----
   - dynamic sampling used for this statement (level=2)

   
   
/************************** mysql library test******************************/

--The version is as follows:

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.1.73    |
+-----------+
1 row in set (0.00 sec)

--Create a test table

mysql>  create table t_index_null(id varchar(50),name varchar(4000));

--Create 100000 test data

insert into t_index_null(id,name) select @a := @a + 1 as seq, 'test'||(@a := @a + 1)   from tmp_seed,(select @a:=0) as seq;


--Add a piece of data with null id

insert into t_index_null(name) values ('zqw01');

--Add a piece of data whose id is null character

insert into t_index_null(id,name) values ('','zqw02');

--Create index on id column

create index idx_t_index_null_id on t_index_null(id);


--Check and lock the data with id=1 to see whether the execution plan will go through the index, and the execution plan will go through the non unique index scanning

explain
select id,name
  from t_index_null 
 where id = '1';
 
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
| id | select_type | table        | type | possible_keys       | key                 | key_len | ref   | rows | Extra       |
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | t_index_null | ref  | idx_t_index_null_id | idx_t_index_null_id | 53      | const |    1 | Using where |
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

--Check and lock the data with id = '' (null character) to see whether the execution plan will go through the index. From the following execution plan, id = '' filtering, and the execution plan will go through the non unique index scanning

explain 
select id,name
  from t_index_null 
 where id = '';

+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
| id | select_type | table        | type | possible_keys       | key                 | key_len | ref   | rows | Extra       |
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | t_index_null | ref  | idx_t_index_null_id | idx_t_index_null_id | 53      | const |    1 | Using where |
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
1 row in set (0.01 sec)

                                   
--Check and lock the data of id is null (null character) to see whether the execution plan will go through the index. From the following execution plan, id is null is also a non unique index scan

explain 
select id,name
  from t_index_null 
 where id is null;
                                                            
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
| id | select_type | table        | type | possible_keys       | key                 | key_len | ref   | rows | Extra       |
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
|  1 | SIMPLE      | t_index_null | ref  | idx_t_index_null_id | idx_t_index_null_id | 53      | const |    1 | Using where |
+----+-------------+--------------+------+---------------------+---------------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

Summary:

If a column in mysql or postgresql database stores null character '' or has null value, then add an index to this column. If SQL uses = '' or is null filtering, the execution plan may go through the index;

If a column in Oracle database stores null character '' or has null value, then add an index to this column. If SQL uses = 'or is null filtering, the SQL execution plan will not go through index scanning;


 

Topics: Database MySQL Oracle PostgreSQL index