You can also use a VIEW.
How does GraphQL make sure to respect table indexes? If not you get a super slow query.
You can still get performance issues with a view if you "select *" on a large amount of data, or join with other views. By exposing the SQL to a web page, you also open up for DDoS attacks more easily, as you can write complex SQL queries
You can get the same problems with GraphQL or stored procedures too of course, if the queries are not optimized correctly
So what's the solution to this?
Performance quotas.
This could be solved by only exposing stored procedures, but that just moves the code to the database server instead of the REST service with the same problems as before.