What is the difference between $wpdb and WP_Query?

$wpdb is a PHP global variable that holds the WordPress database object, which is actually an instantiation of the wpdb class.

WP_Query actually uses wpdb to query the database.

Use WP_Query when you manipulate native WordPress tables (the vast majority of common tasks).

Use $wpdb when you manipulate custom tables.