How does order by row id work in Oracle? - sql

I have a table called points. I executed the following query and expected a list of lexicographicaly sorted list of ROWIDs but that did not happen. How does Order by rowid sorts the row?
select rowid from points order by rowid
I had rows like following
AAAE6MAAFAAABiSAAA
AAAE6MAAFAAABi+AAA
2nd row is lexicographicaly smaller than first row. So what is sorting criteria if it is not lecxicographical sorting?

Why you see is only a representation used for display purposes.
The actual rowid contains binary information about the data block, the row in the block, the file where the block is located and the internal object id of the table (See the manual for details)
When you use order by rowid Oracle sorts the rows based on that (internal) information, not based on the "string representation".
If you change your query to:
select rowid,
dbms_rowid.rowid_relative_fno(rowid) as rel_fno,
dbms_rowid.rowid_row_number(rowid) as row_num,
dbms_rowid.rowid_block_number(rowid) as block_num,
dbms_rowid.rowid_object(rowid)
from points
order by rowid
You will most probably see the logic behind the ordering of the rownumber.
Note that the value for dbms_rowid.rowid_object() will always be the same. And if you only have two rows in your table, both will most probably also have the same value for rowid_block_number()

The sequence of rowid is not guranteed. It depends on how you have set the NLS settings. Also rowid represents the physical allocation of the row in the database. A rowid is considered immutable(does not change) but if you delete a row and insert it again then it changes.
If you delete a row, then Oracle may reassign its rowid to a new row
inserted later.

Related

Oracle primary key seq_id not sort in order in select statement

I defined seq_id column as NUMBER(10), when I select from this table, the record with seq_id = 10 is after shown 1 - not after 9.
How should I make the rows get sorted in numeric order? I know order by seq_id will make it numeric order. But I have seen other tables their counter & seq_id are default in numeric order.
If you don't specify an order by clause the order in which rows are returned is arbitrary. If you care about the order of rows, you must use an order by.
For most tables in simple select statements without a where clause, rows will usually be returned in the way they are physically ordered on disk. For small tables that never undergo deletes, never have updates that cause row migration, and never have multiple threads doing inserts, that physical order is likely to correspond to the numeric order of the sequence. But that is not something that you should depend on.

Why doesn't the last inserted row in Firebird show up at the end of table

When I insert a row in a Firebird database, it doesn't show at the end of the table and it inserted before other row. Why is this?
Firebird doesn't use clustered tables, nor does it order data by insert. When you insert a row, Firebird adds the row to the first datapage of the table it can find that has sufficient space available. As a result, it may end up anywhere relative to other rows of the table.
If you want to enforce a specific order to the data you view, you need to add an order by clause to your select statement, specifying by which columns you want to order the data. Without an order by, the order of the result of a select is not deterministic, and may be the result of physical order in data pages, order of data in an index used to find rows, and other factors.

Auto Increment selection SQLite

I have a column named id in my SQLite database which is auto-increment, Primary Key, Unique.
Is the result of the following query guaranteed to be the smallest value of id in the database and does this correspond to the "oldest" (as in a FIFO) row to be inserted?
SELECT id FROM table LIMIT 1
The SQLite documentation is quite explicit:
If a SELECT statement that returns more than one row does not have an
ORDER BY clause, the order in which the rows are returned is
undefined. Or, if a SELECT statement does have an ORDER BY clause,
then the list of expressions attached to the ORDER BY determine the
order in which rows are returned to the user.
The LIMIT is applied after an ORDER BY would be, so I don't think it affects the application of this statement.
Hence, if you want the first row, use ORDER BY:
SELECT id
FROM table
ORDER BY id
LIMIT 1;
Note that if id is a primary key, this will add basically no overhead.
I should emphasize that in practice you are probably going to get the smallest id without the ORDER BY. However, it is a really, really bad idea to depend on behavior that directly contradicts the documentation.
Is the result of the following query guaranteed to be the smallest value of id in the database
Yes. However if the table is empty or the id column is NULL, it could also return NULL
and does this correspond to the "oldest" (as in a FIFO) row to be inserted?
No, there's no guarantee of that.

rownum in sql query results

i have 10K records in a table and i use rownum to fetch first 5000 records , does frequently accessed records have lower rownum and show up in this first 5000 records when i use rownum with them or it is based on insertion order into the table
ie records inserted first will have a lower rownum and so on.
I m looking at how the Oracle engine decides giving a rownum to a row.
rownum is a pseudo-column that is assigned by the query engine when the results from the query are returned.
It is not assigned to any particular rows in the database. Hence, frequently accessed records have nothing to do with the assignment.
From the documentation
The ROWNUM pseudocolumn returns a number indicating the order in which
Oracle selects the row from a table or set of joined rows.
This is dynamic in nature and allocated only at runtime. So, there is no relationship between ROWNUM and frequently accessed records.
ROWNUM simply assigns a unique number to each row of the result, which can be used to uniquely identify the rows in your result. It is a pseudo column created by the Oracle.
Read Oracle documentation for more details.

SQL Lite blank row id even after deleting the row

I have a SQLite DB file lets say a.db. And I have 100 rows in table a. When I give
SELECT * FROM a WHERE rowid BETWEEN 1 AND 100
it gives me the first 100 results. Now if I delete the first 2 rows from the table and run the
SELECT * FROM a WHERE rowid BETWEEN 1 AND 100
it gives me only 98 rows. And when I give the query
SELECT * FROM a WHERE rowid = 1
it gives me an empty row. The database doesn't seem to rearrange the rowid.
Please help.. Is there any way to force the SQLite to rearrange the row ids ?
In SQLite, rowid is just an int column with autoincremented values. The only thing you're guaranteed is that each rowid will be unique to that table -- nothing more. You aren't guaranteed that rowids will be sequential, and you aren't even guaranteed that every number will be used! For example, if an INSERT fails, the rowid used in that failed insert will probably be skipped and never used again (if the autoincrement keyword is explicitly used -- otherwise, if a row is deleted, its rowid is free to be reused by any newly inserted data.)
If you want rowids to be sequential and autoupdated, you'll have to create your own version of the rowid column and keep it updated with triggers.
I found out the answer. We need to run the Vacuum query after every delete. This will rearrange all the rowindex and remove the dead rows.
http://sqlite.org/lang_vacuum.html