@Marc_s answer is very good and I have been using it for several years now. However, I noticed that the script skips data in some columnstore indices and does not show the whole picture. For example, when you execute SUM(TotalSpace) for a script and compare it with the property of the shared space database in Management Studio, in my case the numbers do not match (Management Studio shows large numbers). I modified the script to overcome this problem and expanded it a bit:
select tables.[name] as table_name, schemas.[name] as schema_name, isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown') as database_name, sum(allocation_units.total_pages) * 8 as total_space_kb, cast(round(((sum(allocation_units.total_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as total_space_mb, sum(allocation_units.used_pages) * 8 as used_space_kb, cast(round(((sum(allocation_units.used_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as used_space_mb, (sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8 as unused_space_kb, cast(round(((sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8) / 1024.00, 2) as numeric(36, 2)) as unused_space_mb, count(distinct indexes.index_id) as indexes_count, max(dm_db_partition_stats.row_count) as row_count, iif(max(isnull(user_seeks, 0)) = 0 and max(isnull(user_scans, 0)) = 0 and max(isnull(user_lookups, 0)) = 0, 1, 0) as no_reads, iif(max(isnull(user_updates, 0)) = 0, 1, 0) as no_writes, max(isnull(user_seeks, 0)) as user_seeks, max(isnull(user_scans, 0)) as user_scans, max(isnull(user_lookups, 0)) as user_lookups, max(isnull(user_updates, 0)) as user_updates, max(last_user_seek) as last_user_seek, max(last_user_scan) as last_user_scan, max(last_user_lookup) as last_user_lookup, max(last_user_update) as last_user_update, max(tables.create_date) as create_date, max(tables.modify_date) as modify_date from sys.tables left join sys.schemas on schemas.schema_id = tables.schema_id left join sys.indexes on tables.object_id = indexes.object_id left join sys.partitions on indexes.object_id = partitions.object_id and indexes.index_id = partitions.index_id left join sys.allocation_units on partitions.partition_id = allocation_units.container_id left join sys.dm_db_index_usage_stats on tables.object_id = dm_db_index_usage_stats.object_id and indexes.index_id = dm_db_index_usage_stats.index_id left join sys.dm_db_partition_stats on tables.object_id = dm_db_partition_stats.object_id and indexes.index_id = dm_db_partition_stats.index_id group by schemas.[name], tables.[name], isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown') order by 5 desc
Hope this will be helpful to someone. This script has been tested with large databases throughout the TB with hundreds of different tables, indexes, and schemas.