Table in which RowCount is stored in Sybase ASE - sql

Is there any system table in Sybase ASE which stores rowcount of all the user tables? I would like to avoid count(*). I know that we get rowcount when we use sp_help. So thought that it must be stored in any of system tables.

I haven't use this feature in Sybase, but Sybase is quite similar to SQL Server. Perusing through the documentation, it would seem that the field is in systabstats.rowcnt. This would result in a query something like this:
select o.name, s.rowcnt
from systabstats s join
sysobjects o
on s.id = o.id
where s.indid = 0;
I would imagine that this column is an approximation, and might be off in a high transaction environment.

You should not use the systabstats.rowcnt column: this information depends n whether the statistics have been updated. It is much better to use the row_count() function in a query against sysindexes. Unlike systabstats, this information is maintained automatically. Only when insert/delete activity is happening on the table can the result returned by this function temporarily be off by a small numbers of rows.
As for MSSQL Server still being similar to Sybase ASE: that's true on the outside. Microsoft has made many changes to the internals, and as a result the two databases are very different under the covers. Things like statistics and storage (both which we're discussing above) fall in this category.

If you are running SybaseASE pre 15.0 then
SELECT o.name,
ROWCNT(i.doampg) as ROW_COUNT
FROM sysobjects o,
sysindexes i
WHERE o.id = i.id
AND o.sysstat2 & 1024 = 0 -- not remote
AND o.sysstat2 & 2048 = 0 -- not proxy
AND (i.indid = 0 OR i.indid = 1) -- Heap or ClustIdx only
--AND ROWCNT(i.doampg) > 1000 -- only need for tables having more than 1000 rows
AND o.type = 'U' -- exclude system tables
ORDER BY o.name
If you are running sybase 15.0 and up then you can use ROW_COUNT() function ;
SELECT name,
ROW_COUNT(DB_ID(), id)
FROM sysobjects
WHERE type = "U"
AND sysstat2 & 1024 = 0 -- not remote
AND sysstat2 & 2048 = 0 -- not proxy
ORDER BY name

You could use systabstats.rowcnt or row_count (i.doampg) from sysindexes (ase15)

Related

How to get column names from a query in SQL Server

Using SQL Server.
I have a very extensive query, with a lot of aliasing, etc...
Is there a way, using just SQL (stored proc is fine, but not PHP, etc), to get a list of all column names from this query? (I realize I will have to probably embed my query inside of this solution but that is fine. Just a temporary measure.)
Thanks!
If you're using SQL Server 2012 or later you can take advantage of sys.dm_exec_describe_first_result_set
SELECT name
FROM
sys.dm_exec_describe_first_result_set
('Your Query Here', NULL, 0) ;
DEMO
There are various ways that you can get the columns out of the query, such as:
select top 0 s.*
from (<your query here>) s;
Then you can parse the results.
However, I have found another approach useful. Create either a view or a table using the same logic:
select top 0 s.*
into _TempTableForColumns
from (<your query here>) s;
Then use information_schema (or the system tables if you prefer):
select *
from information_schema.columns
where table_name = '_TempTableForColumns' and schema_name = 'dbo';
drop table _TempTableForColumns;
The advantage of this approach is that you can get type information along with the column names. But the engine still has to run the query and that might take time even though no rows are returned. Although the column names and types are available after compiling, I am not aware of a way to get them without also executing the query.
After SQL Server 2008
select *
from sys.columns c
inner join sys.objects o on c.object_id = o.object_id
where o.name = 'TableName'
Before
select *
from syscolumns c
inner join sysobjects o on c.id = o.id
where o.name = 'TableName'

Query runs forever ORACLE

Am trying to update the isdeleted column in one table when a record is not in the other user table . My problem is the query l have written runs forever. how best can l write the query below.
update TBLG2O_REGISTER a set a."isDeleted" = '1'
where a."UserID" not in (select k."UserID" from TBLG2O_USER k)
The answer is going to be database engine-specific. Performance characteristic differ wildly, across different database engines, and you failed to specify which DB server you are using.
However, subqueries are frequently MySQL's Achilles heel; I wouldn't be surprised that if this was MySQL. If so, the following approach should have better performance characteristics with MySQL:
update TBLG2O_REGISTER a left join TBLG20_USER k using(UserID)
set a.isDeleted = '1' where k.UserID is null;
Finally got it to work Thank you for your help
Update TBLG2O_REGISTER a set a."isDeleted" = '1' where a."UserID" in (select p."UserID"
from TBLG2O_REGISTER p left join TBLG2O_USER k on p."UserID" =k."UserID"
where k."UserID" is null)

calculating the size of sql server database

I need to find the size of a sql server 2008 database. I used the following stored procedure
EXEC sp_spaceused
If gave me back the following data, database name, database size, unallocated space, reserved, data, index_size, unused
Is there any way I can get the size of the database, excluding certain tables?
I am able to get the reserved size of each database table using this query
DECLARE #LOW int
SELECT #LOW = LOW
FROM [master].[dbo].[spt_values] (NOLOCK)
WHERE [number] = 1 AND [type] = 'E'
SELECT TableName,[Row Count],[Size (KB)] FROM
(
SELECT QUOTENAME(USER_NAME(o.uid)) + '.' +
QUOTENAME(OBJECT_NAME(i.id))
AS TableName
,SUM(i.rowcnt) [Row Count]
,CONVERT(numeric(15,2),
(((CONVERT(numeric(15,2),SUM(i.reserved)) * #LOW) / 1024))) AS [Size (KB)]
FROM sysindexes i (NOLOCK)
INNER JOIN sysobjects o (NOLOCK)
ON i.id = o.id AND
((o.type IN ('U', 'S')) OR o.type = 'U')
WHERE indid IN (0, 1, 255)
GROUP BY
QUOTENAME(USER_NAME(o.uid)) + '.' +
QUOTENAME(OBJECT_NAME(i.id))
HAVING SUM(i.rowcnt) > 0
) AS Z
ORDER BY [Size (KB)] DESC
But this confuses me slightly, as this only gives the reserved size per table. What is the reserved size? If I sum the reserved size for each database table, it does not add up to the database size.
There is a lot more taking up space in a database than just tables. Also keep in mind that the size of a table/database is an ever changing thing. Rows are added, removed, logs are built to keep track of what was done so it can undo or redo if necessary. As this space is used and released it doesn't typically get released back to the file system as SQL knows it will likely need it again. SQL will release space for it's own future usage but according to the file system that space is still being used by the database.
Please stop using backward compatibility views like sysindexes / sysobjects.
Something like this might be better, though indexes/tables alone do not account for everything in a database.
SELECT Size_In_MB = SUM(reserved_page_count)*8/1024.0
FROM sys.dm_db_partition_stats
WHERE OBJECT_NAME([object_id]) NOT IN (N'table1', N'table2');
Also, why are you ignoring non-clustered indexes? Do you think they don't contribute to size? You can add a similar filter here, but I'm not sure why you would:
AND index_id IN (0,1,255);

Finding Indexes For A Table in Sybase

I am currently working in an environment where I am made double blind.
I have to email any queries I need to run to a employee of the client
That employee runs them in a SAS client, with an odbc connection to SyBase
I need to find out how to ascertain exactly what indexes exist on a specific table. I would use sp_helpindex, but apparently it doesn't exist on their instance of SyBase.
We believe that it is SyBase 12, but again I can't be certain of anything.
Does anyone have SQL for...
- Confirming exactly what version of SyBase we're working on?
- The details of all indexes that exist for a given table?
Most Sybase products have a -v command line argument to tell the version with or without the engine running.
To find the indexes on any table enter the following, where my_table is your table's name:
select i.name
from sysindexes i, sysobjects o
where o.name = 'my_table'
and o.id = i.id
To "Confirming exactly what version of SyBase we're working on?"
Why not use:
select ##version
Sybase website is down (at least here), but it would be something like:
IQ SHOW INDEXSET INDEXES
or
IQ SHOW INDEXSET FOR indexset
where indexset is tablename because every table has a indexset assigned with the same name.
If you have access to sybase website possibly you can go further :)
You can use this query:
select i.name
from sysindexes i, sysobjects o
where o.name = 'table_name' and i.indid >=1
and o.id = i.id
Find Indexes on multiple tables, not like image indexes
select name = o.name,iname = i.name from sysindexes i, sysobjects o where o.name in ('table1','table2','table3') and i.name not like 't%' and i.indid >=1 and o.id = i.id
For sybase version:
select ##version
in Sybase version SAP IQ/16, you can get list of indexes with following (table name my_table is case sensitive:
select *
from sys.sysindexes
where tname = 'my_table';
select * from sys.sysindexes where tname='Your Table name'
Try the above code, it worked for me.

SQL2000 to SQL2005. Query now a lot slower

This query used to take 3secs in SQL2000, now it takes about 70secs. Both databases give the same results. The 2005 database is not running in compatibility mode.
Currently we're rebuilding the query to run in SQL2005.. by a process of elimination and understanding the logic.
However - can anyone see anything obvious that we've missed.
And/or are there any tools that could help here?
We've been looking at the Execution plan... and profiler. And index tuning wizard.
Profiler points to a massive number more records being queried to get the same results.
I know that this is a very hard question to debug without the data... another pair of eyes is always good if there is anything obvious!
Cheers
Dave
ALTER PROCEDURE [dbo].[GetNodeList]
#ViewID int,
#UserID int = null
as
Select ProcessList.*,
A.NDOC_DOC_ID,
A.NDOC_Order,
A.OMNIBOOK_ID,
A.Node_Order
from (
(SELECT N.NOD_ID,
N.NOD_Name,
N.NOD_Procname,
N.NOD_Xpos,
N.NOD_Ypos,
N.NOD_Zpos,
VN.VNOD_VIE_ID
FROM Node N
INNER JOIN View_NODe VN
ON N.NOD_ID = VN.VNOD_NOD_ID
Where VN.VNOD_VIE_ID = #ViewID) ProcessList
Left Join
(
SELECT N.NOD_ID,
N.NOD_Name,
N.NOD_Procname,
N.NOD_Xpos as NOD_Xpos,
N.NOD_Ypos as NOD_Ypos,
N.NOD_Zpos as NOD_Zpos,
VN.VNOD_VIE_ID,
ND.NDOC_DOC_ID as NDOC_DOC_ID,
ND.NDOC_Order as NDOC_Order,
null as OMNIBOOK_ID,
null as Node_Order
FROM Node N
INNER JOIN View_NODe VN
ON N.NOD_ID = VN.VNOD_NOD_ID
LEFT JOIN NODe_DOCument ND
ON N.NOD_ID = ND.NDOC_NOD_ID
WHERE VN.VNOD_VIE_ID=#ViewID
and ND.NDOC_DOC_ID is not null
and (#UserID is null
or exists (Select 1
from Document D
where Doc_ID = ND.NDOC_DOC_ID
and dbo.fn_UserCanSeeDoc(#UserID,D.Doc_ID)<>0
)
)
UNION
SELECT N.NOD_ID,
N.NOD_Name,
N.NOD_Procname,
N.NOD_Xpos,
N.NOD_Ypos,
N.NOD_Zpos,
VN.VNOD_VIE_ID,
null,
null,
NOM.OMNIBOOK_ID,
NOM.Node_Order
FROM Node N
INNER JOIN View_NODe VN
ON N.NOD_ID = VN.VNOD_NOD_ID
LEFT JOIN NODe_OMNIBOOK NOM
ON N.NOD_ID = NOM.NODE_ID
WHERE VN.VNOD_VIE_ID=#ViewID
and NOM.OMNIBOOK_ID is not null
and exists (select 1 from Omnibook_Doc where OmnibookID = NOM.OMNIBOOK_ID)
) A
--On ProcessList.NOD_ID = A.NOD_ID
ON ProcessList.NOD_Xpos = A.NOD_Xpos
And ProcessList.NOD_Ypos = A.NOD_Ypos
And ProcessList.NOD_Zpos = A.NOD_Zpos
And ProcessList.VNOD_VIE_ID = A.VNOD_VIE_ID
)
ORDER BY
ProcessList.NOD_Xpos,
ProcessList.NOD_Zpos,
ProcessList.NOD_Ypos,
Coalesce(A.NDOC_Order,A.Node_Order),
Coalesce(A.NDOC_DOC_ID,A.OMNIBOOK_ID)
I've seen this before when the statistics haven't kept up with the data. It's possible in this instance that SQL Server 2005 uses the statistics differently to SQL Server 2000. Try rebuilding your statistics for the tables used in the query; so for each table:
UPDATE STATISTICS <table> WITH FULLSCAN
Yes, I'd add the FULLSCAN unless you know your data well enough to think that a sample of records will give good enough results. It'll slow down the stats creation, but will make it more accurate.
Is it possible that your statistics haven't come across? in the 2k5 dbase? So the dbase doesn't have the info needed to make a good plan? As opposed to your old database which has good stats on the table and can choose a better plan for the data?
Could it be an issue with "parameter sniffing", i.e. SQL Server caching a query plan optimized for the parameters supplied for the first execution?
Microsoft technet has more
A college has come up with a solution... regarding bringing the function fn_UserCanSeeDoc back into the SQL.
Shown below is the old commented out function code, then the new inline SQL below it. The code now runs super quick (from over 1 minute to about a second)
Looking at the old SQL I'm surprised how good a job SQL2000 did of running it!
Cheers
--and dbo.fn_UserCanSeeDoc(#UserID,D.Doc_ID)<>0
-- if exists(Select 1 from Omnibook where Omnibook_ID = #DocID)
-- Begin
-- Set #ReturnVal = 1
-- End
--
-- else
-- Begin
-- if exists(
-- Select 1
-- from UserSecurityModule USM
-- Inner join DocSecurity DS
-- On USM.SecurityModuleID = DS.SecurityModuleID
-- where USM.UserID = #UserID
-- and DS.DocID = #DocID
-- )
--
-- Set #ReturnVal = 1
--
-- else
--
-- Set #ReturnVal = 0
-- End
AND D.Doc_ID IN (select DS.DocID from UserSecurityModule USM
Inner join DocSecurity DS
On USM.SecurityModuleID = DS.SecurityModuleID
where USM.UserID = #UserID)