Find Size of a Database in Oracle - database

I have a database named "My_Enterprise_Data". I need to find the size that it occupies on the disk.
How do I find it out?
Is the query, SELECT sum(bytes)/1024/1024 AS "Size in MB" FROM user_segments run against the My_Enterprise_Data correct?

The following will show you the data files used by oracle:
select TABLESPACE_NAME "Tablspace",
FILE_NAME "Filename",
BYTES/1024/1024 "Size MB",
MAXBYTES/1024/1024 "Maximum Size MB",
AUTOEXTENSIBLE "Autoextensible"
from SYS.DBA_DATA_FILES
You can then look for the tablespace used by the My_Enterprise_Data schema

An oracle database consists of data files, redo log files, control files, temporary files.
The size of the database actually means the total size of all these files.
select
( select sum(bytes)/1024/1024/1024 data_size from dba_data_files ) +
( select nvl(sum(bytes),0)/1024/1024/1024 temp_size from dba_temp_files ) +
( select sum(bytes)/1024/1024/1024 redo_size from sys.v_$log ) +
( select sum(BLOCK_SIZE*FILE_SIZE_BLKS)/1024/1024/1024 controlfile_size from v$controlfile) "Size in GB"
from
dual

SELECT a.data_size + b.temp_size + c.redo_size + d.controlfile_size
"total_size in GB"
FROM (SELECT SUM (bytes) / 1024 / 1024/1024 data_size FROM dba_data_files) a,
(SELECT NVL (SUM (bytes), 0) / 1024 / 1024/1024 temp_size
FROM dba_temp_files) b,
(SELECT SUM (bytes) / 1024 / 1024/1024 redo_size FROM sys.v_$log) c,
(SELECT SUM (BLOCK_SIZE * FILE_SIZE_BLKS) / 1024 / 1024/1024
controlfile_size
FROM v$controlfile) d;

Great... dba_segments gives the Oracle database size
To find the actual space occupied by the database.
Select sum(bytes)/1024/1024/1024 from dba_segments;

Related

Bitwise & operator in Snowflake?

I'm stuck with Snowflake about bitwise operators. In MySql it's allowed to use this syntax:
Flag & 1024 > 0
I'd like to make the same filtering in the where clause with Snowflake but I've found only these function on the web:
https://docs.snowflake.com/en/sql-reference/expressions-byte-bit.html
Do you have any ideal how to do the same thing?
The Flag & 1024 > 0 is equivalent of BITWISE AND:
WHERE BITAND(Flag, 1024) > 0;
db<> fiddle demo MySQL
Snowflake:
CREATE TABLE tab(flag INT)
AS
SELECT 1024 AS flag
UNION SELECT 2048
UNION SELECT 1025;
SELECT *
FROM tab
WHERE BITAND(Flag, 1024) > 0;
-- 1024
-- 1025

Space consumed by a particular column's data and impact on deleting that column

I am using Oracle 12c database in my project and I have a column "Name" of type "VARCHAR2(128 CHAR) NOT NULL ". I have approximately 25328687 rows in my table.
Now I don't need the "Name" column so I want to delete it. When I calculated the total size of the data in this column(using lengthb and vsize) for all the rows it was approximately 1.07 GB.
Since the max size of the data in this column is specified, isn't all the rows will be allocated 128 bytes for this column (ignoring unicode for simplicity) and the total space consumed by this column should be 128 * number of rows = 3242071936 bytes or 3.24 GB.
Oracle Varchar2 allocate memory dynamically (definition says variable length string data type)
Char datatype is fixed length string data type.
create table x (a char(5), b varchar2(5));
insert into x value ('RAM', 'RAM');
insert into x value ('RAMA', 'RAMA');
insert into x value ('RAMAN', 'RAMAN');
SELECT * FROM X WHERE length(a) = 3; -> this will return 0 record
SELECT * FROM X WHERE length(b) = 3; -> this will return 1 record (RAM)
SELECT length(a) len_a, length(b) len_b from x ;
o/p will be like below
len_a | len_b
-------------
5 | 3
5 | 4
5 | 5
Oracle do dynamic allocation for varchar2 .
So a string of 4 char will take 5 bytes one for the length and 4 bytes for 4 char , if one-byte character set .
As the other answers say, the storage that a VARCHAR2 column uses is VARying. To get an estimate of the actual amount, you can use
1) The data dictionary
SELECT column_name, avg_col_len, last_analyzed
FROM ALL_TAB_COL_STATISTICS
WHERE owner = 'MY_SCHEMA'
AND table_name = 'MY_TABLE'
AND column_name = 'MY_COLUMN';
The result avg_col_len is the average column length. Mulitply it by your number of rows 25328687 and you get an estimate of roughly how many bytes this column uses. (If last_analyzed is NULL or very old compared to the last big data change, you'll have to refresh the optimizer stats with DBMS_STATS.GATHER_TABLE_STATS('MY_SCHEMA','MY_TABLE') first.
2) Count yourself in sample
SELECT sum(s), count(*), avg(s), stddev(s)
FROM (
SELECT vsize(my_column) as s
FROM my_schema.my_table SAMPLE (0.1)
);
This calculates the storage size of a 0.1 percent sample of your table.
3) To know for sure, I'd do a test of with a subset of the data
CREATE TABLE my_test TABLESPACE my_scratch_tablespace NOLOGGING AS
SELECT * FROM my_schema.my_table SAMPLE (0.1);
-- get the size of the test table in megabytes
SELECT round(bytes/1024/1024) as mb
FROM dba_segments WHERE owner='MY_SCHEMA' AND segment_name='MY_TABLE';
-- now drop the column
ALTER TABLE my_test DROP (my_column);
-- and measure again
SELECT round(bytes/1024/1024) as mb
FROM dba_segments WHERE owner='MY_SCHEMA' AND segment_name='MY_TABLE';
-- check how much space will be freed up
ALTER TABLE my_test MOVE;
SELECT round(bytes/1024/1024) as mb
FROM dba_segments WHERE owner='MY_SCHEMA' AND segment_name='MY_TABLE';
You could improve the test by using the same PCTFREE and COMPRESSION levels on your test table.

What is an efficient algorithm to input 4B integers to a text file

Let's say I want to write 1,2,3,4....up to 4.096B in a text file. What would be a time efficient way to do it. Just doing it sequentially is taking a long time. So wondering if there's a distributed way.
Thanks to all your comments on my question. It helped me solve this problem in a reasonable amount of time. Here's what I did -
Create a file using Excel to create a million integers from 0 - 1000000
Upload this file in Hadoop
Write a Hive query with 4296 lines like below -
a0 = SELECT IPDecimal + (100000 * 1) + 1 AS IPDecimal FROM #file;
a1 = SELECT IPDecimal + (100000 * 2) + 1 AS IPDecimal FROM #file;
.
.
.
a4295 = SELECT IPDecimal + (100000 * 4295) + 1 AS IPDecimal FROM #file;
Output the result of each SELECT statement above in a separate file and then consolidate the integers in the 4296 files in one single file

SQL Server : datalength conversion

I have a table dbo.files with 9 columns that include file_size and created_time and filepath.
Sample values:
file_size = 528300
created_time = 2012-06-28 09:31:17.610
I have the following query where I'm trying to show the total # of MB have been written to the filesystem 'today' by these files.
select
sum(datalength(f.file_size)) / 1048576.0 AS 'Storage Used Today"
from
dbo.files AS f
where
f.created_time >= CAST(getdate() as DATE)
and f.created_time < CAST(DATEADD(day, 1, getdate()) as DATE)
The result is '0.173525810'. Is there a way to move that decimal over to show the proper value?
Thanks
SUM(DATALENGTH(x)) tells you the size in bytes of the numeric representation.
Which isn't what you need.
For example if the datatype was integer (4 bytes) and you had three rows with none null values in the column it would evaluate to 12 irrespective of the actual numeric contents.
Just remove the function call.
sum(f.file_size) / (1024.0 * 1024)
Will work fine

How to limit rows in SELECT with TRANSBASE

I'm working with huge records amount in one table and i need to SELECT them in 50000 pages. Is it possible somehow to limit these pages so the query would be faster and row count will be limited and offsetted?
I'm using ODBC with php like this:
$odbc_query = "SELECT * FROM " . $table_name;
$data = odbc_exec($this->odbc_id, $odbc_query);
while($row = odbc_fetch_array($data))
{
The limit is possible by FIRST(limit):
SELECT * FROM tablename FIRST(1000);
u can use limit keyword to limit the number of records...
select * from tablename limit 1000;
this will give u first 1000 rows..
now next time u want next thousand for this u have to keep track of ur last position.
so the query becomes...
select * from tablename limit 1000 offset by lastposition;

Resources